LCOV - code coverage report
Current view: top level - g10 - card-util.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1019 0.0 %
Date: 2015-11-05 17:10:59 Functions: 0 38 0.0 %

          Line data    Source code
       1             : /* card-util.c - Utility functions for the OpenPGP card.
       2             :  * Copyright (C) 2003-2005, 2009 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2003-2005, 2009 Werner Koch
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       7             :  * GnuPG is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published by
       9             :  * the Free Software Foundation; either version 3 of the License, or
      10             :  * (at your option) any later version.
      11             :  *
      12             :  * GnuPG is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h>
      25             : #include <errno.h>
      26             : #include <assert.h>
      27             : #ifdef HAVE_LIBREADLINE
      28             : # define GNUPG_LIBREADLINE_H_INCLUDED
      29             : # include <readline/readline.h>
      30             : #endif /*HAVE_LIBREADLINE*/
      31             : 
      32             : #if GNUPG_MAJOR_VERSION != 1
      33             : # include "gpg.h"
      34             : #endif /*GNUPG_MAJOR_VERSION != 1*/
      35             : #include "util.h"
      36             : #include "i18n.h"
      37             : #include "ttyio.h"
      38             : #include "status.h"
      39             : #include "options.h"
      40             : #include "main.h"
      41             : #include "keyserver-internal.h"
      42             : 
      43             : #if GNUPG_MAJOR_VERSION == 1
      44             : # include "cardglue.h"
      45             : #else /*GNUPG_MAJOR_VERSION!=1*/
      46             : # include "call-agent.h"
      47             : #endif /*GNUPG_MAJOR_VERSION!=1*/
      48             : 
      49             : #define CONTROL_D ('D' - 'A' + 1)
      50             : 
      51             : 
      52             : static void
      53           0 : write_sc_op_status (gpg_error_t err)
      54             : {
      55           0 :   switch (gpg_err_code (err))
      56             :     {
      57             :     case 0:
      58           0 :       write_status (STATUS_SC_OP_SUCCESS);
      59           0 :       break;
      60             : #if GNUPG_MAJOR_VERSION != 1
      61             :     case GPG_ERR_CANCELED:
      62             :     case GPG_ERR_FULLY_CANCELED:
      63           0 :       write_status_text (STATUS_SC_OP_FAILURE, "1");
      64           0 :       break;
      65             :     case GPG_ERR_BAD_PIN:
      66           0 :       write_status_text (STATUS_SC_OP_FAILURE, "2");
      67           0 :       break;
      68             :     default:
      69           0 :       write_status (STATUS_SC_OP_FAILURE);
      70           0 :       break;
      71             : #endif /* GNUPG_MAJOR_VERSION != 1 */
      72             :     }
      73           0 : }
      74             : 
      75             : 
      76             : /* Change the PIN of a an OpenPGP card.  This is an interactive
      77             :    function. */
      78             : void
      79           0 : change_pin (int unblock_v2, int allow_admin)
      80             : {
      81             :   struct agent_card_info_s info;
      82             :   int rc;
      83             : 
      84           0 :   rc = agent_scd_learn (&info, 0);
      85           0 :   if (rc)
      86             :     {
      87           0 :       log_error (_("OpenPGP card not available: %s\n"),
      88             :                   gpg_strerror (rc));
      89           0 :       return;
      90             :     }
      91             : 
      92           0 :   log_info (_("OpenPGP card no. %s detected\n"),
      93           0 :               info.serialno? info.serialno : "[none]");
      94             : 
      95           0 :   agent_clear_pin_cache (info.serialno);
      96             : 
      97           0 :   if (opt.batch)
      98             :     {
      99           0 :       agent_release_card_info (&info);
     100           0 :       log_error (_("can't do this in batch mode\n"));
     101           0 :       return;
     102             :     }
     103             : 
     104             : 
     105           0 :   if (unblock_v2)
     106             :     {
     107           0 :       if (!info.is_v2)
     108           0 :         log_error (_("This command is only available for version 2 cards\n"));
     109           0 :       else if (!info.chvretry[1])
     110           0 :         log_error (_("Reset Code not or not anymore available\n"));
     111             :       else
     112             :         {
     113           0 :           rc = agent_scd_change_pin (2, info.serialno);
     114           0 :           write_sc_op_status (rc);
     115           0 :           if (rc)
     116           0 :             tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
     117             :           else
     118           0 :             tty_printf ("PIN changed.\n");
     119             :         }
     120             :     }
     121           0 :   else if (!allow_admin)
     122             :     {
     123           0 :       rc = agent_scd_change_pin (1, info.serialno);
     124           0 :       write_sc_op_status (rc);
     125           0 :       if (rc)
     126           0 :         tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
     127             :       else
     128           0 :         tty_printf ("PIN changed.\n");
     129             :     }
     130             :   else
     131             :     for (;;)
     132             :       {
     133             :         char *answer;
     134             : 
     135           0 :         tty_printf ("\n");
     136           0 :         tty_printf ("1 - change PIN\n"
     137             :                     "2 - unblock PIN\n"
     138             :                     "3 - change Admin PIN\n"
     139             :                     "4 - set the Reset Code\n"
     140             :                     "Q - quit\n");
     141           0 :         tty_printf ("\n");
     142             : 
     143           0 :         answer = cpr_get("cardutil.change_pin.menu",_("Your selection? "));
     144           0 :         cpr_kill_prompt();
     145           0 :         if (strlen (answer) != 1)
     146           0 :           continue;
     147             : 
     148           0 :         rc = 0;
     149           0 :         if (*answer == '1')
     150             :           {
     151             :             /* Change PIN.  */
     152           0 :             rc = agent_scd_change_pin (1, info.serialno);
     153           0 :             write_sc_op_status (rc);
     154           0 :             if (rc)
     155           0 :               tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
     156             :             else
     157           0 :               tty_printf ("PIN changed.\n");
     158             :           }
     159           0 :         else if (*answer == '2')
     160             :           {
     161             :             /* Unblock PIN.  */
     162           0 :             rc = agent_scd_change_pin (101, info.serialno);
     163           0 :             write_sc_op_status (rc);
     164           0 :             if (rc)
     165           0 :               tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc));
     166             :             else
     167           0 :               tty_printf ("PIN unblocked and new PIN set.\n");
     168             :           }
     169           0 :         else if (*answer == '3')
     170             :           {
     171             :             /* Change Admin PIN.  */
     172           0 :             rc = agent_scd_change_pin (3, info.serialno);
     173           0 :             write_sc_op_status (rc);
     174           0 :             if (rc)
     175           0 :               tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc));
     176             :             else
     177           0 :               tty_printf ("PIN changed.\n");
     178             :           }
     179           0 :         else if (*answer == '4')
     180             :           {
     181             :             /* Set a new Reset Code.  */
     182           0 :             rc = agent_scd_change_pin (102, info.serialno);
     183           0 :             write_sc_op_status (rc);
     184           0 :             if (rc)
     185           0 :               tty_printf ("Error setting the Reset Code: %s\n",
     186             :                           gpg_strerror (rc));
     187             :             else
     188           0 :               tty_printf ("Reset Code set.\n");
     189             :           }
     190           0 :         else if (*answer == 'q' || *answer == 'Q')
     191             :           {
     192             :             break;
     193             :           }
     194           0 :       }
     195             : 
     196           0 :   agent_release_card_info (&info);
     197             : }
     198             : 
     199             : static const char *
     200           0 : get_manufacturer (unsigned int no)
     201             : {
     202             :   /* Note:  Make sure that there is no colon or linefeed in the string. */
     203           0 :   switch (no)
     204             :     {
     205           0 :     case 0x0001: return "PPC Card Systems";
     206           0 :     case 0x0002: return "Prism";
     207           0 :     case 0x0003: return "OpenFortress";
     208           0 :     case 0x0004: return "Wewid";
     209           0 :     case 0x0005: return "ZeitControl";
     210           0 :     case 0x0006: return "Yubico";
     211           0 :     case 0x0007: return "OpenKMS";
     212           0 :     case 0x0008: return "LogoEmail";
     213           0 :     case 0x0009: return "Fidesmo";
     214             : 
     215           0 :     case 0x002A: return "Magrathea";
     216             : 
     217           0 :     case 0x1337: return "Warsaw Hackerspace";
     218             : 
     219           0 :     case 0xF517: return "FSIJ";
     220             : 
     221             :       /* 0x0000 and 0xFFFF are defined as test cards per spec,
     222             :          0xFF00 to 0xFFFE are assigned for use with randomly created
     223             :          serial numbers.  */
     224             :     case 0x0000:
     225           0 :     case 0xffff: return "test card";
     226           0 :     default: return (no & 0xff00) == 0xff00? "unmanaged S/N range":"unknown";
     227             :     }
     228             : }
     229             : 
     230             : 
     231             : static void
     232           0 : print_sha1_fpr (estream_t fp, const unsigned char *fpr)
     233             : {
     234             :   int i;
     235             : 
     236           0 :   if (fpr)
     237             :     {
     238           0 :       for (i=0; i < 20 ; i+=2, fpr += 2 )
     239             :         {
     240           0 :           if (i == 10 )
     241           0 :             tty_fprintf (fp, " ");
     242           0 :           tty_fprintf (fp, " %02X%02X", *fpr, fpr[1]);
     243             :         }
     244             :     }
     245             :   else
     246           0 :     tty_fprintf (fp, " [none]");
     247           0 :   tty_fprintf (fp, "\n");
     248           0 : }
     249             : 
     250             : 
     251             : static void
     252           0 : print_sha1_fpr_colon (estream_t fp, const unsigned char *fpr)
     253             : {
     254             :   int i;
     255             : 
     256           0 :   if (fpr)
     257             :     {
     258           0 :       for (i=0; i < 20 ; i++, fpr++)
     259           0 :         es_fprintf (fp, "%02X", *fpr);
     260             :     }
     261           0 :   es_putc (':', fp);
     262           0 : }
     263             : 
     264             : 
     265             : static void
     266           0 : print_name (estream_t fp, const char *text, const char *name)
     267             : {
     268           0 :   tty_fprintf (fp, "%s", text);
     269             : 
     270             :   /* FIXME: tty_printf_utf8_string2 eats everything after and
     271             :      including an @ - e.g. when printing an url. */
     272           0 :   if (name && *name)
     273             :     {
     274           0 :       if (fp)
     275           0 :         print_utf8_buffer2 (fp, name, strlen (name), '\n');
     276             :       else
     277           0 :         tty_print_utf8_string2 (NULL, name, strlen (name), 0);
     278             :     }
     279             :   else
     280           0 :     tty_fprintf (fp, _("[not set]"));
     281           0 :   tty_fprintf (fp, "\n");
     282           0 : }
     283             : 
     284             : static void
     285           0 : print_isoname (estream_t fp, const char *text,
     286             :                const char *tag, const char *name)
     287             : {
     288           0 :   if (opt.with_colons)
     289           0 :     es_fprintf (fp, "%s:", tag);
     290             :   else
     291           0 :     tty_fprintf (fp, "%s", text);
     292             : 
     293           0 :   if (name && *name)
     294           0 :     {
     295           0 :       char *p, *given, *buf = xstrdup (name);
     296             : 
     297           0 :       given = strstr (buf, "<<");
     298           0 :       for (p=buf; *p; p++)
     299           0 :         if (*p == '<')
     300           0 :           *p = ' ';
     301           0 :       if (given && given[2])
     302             :         {
     303           0 :           *given = 0;
     304           0 :           given += 2;
     305           0 :           if (opt.with_colons)
     306           0 :             es_write_sanitized (fp, given, strlen (given), ":", NULL);
     307           0 :           else if (fp)
     308           0 :             print_utf8_buffer2 (fp, given, strlen (given), '\n');
     309             :           else
     310           0 :             tty_print_utf8_string2 (NULL, given, strlen (given), 0);
     311             : 
     312           0 :           if (opt.with_colons)
     313           0 :             es_putc (':', fp);
     314           0 :           else if (*buf)
     315           0 :             tty_fprintf (fp, " ");
     316             :         }
     317             : 
     318           0 :       if (opt.with_colons)
     319           0 :         es_write_sanitized (fp, buf, strlen (buf), ":", NULL);
     320           0 :       else if (fp)
     321           0 :         print_utf8_buffer2 (fp, buf, strlen (buf), '\n');
     322             :       else
     323           0 :         tty_print_utf8_string2 (NULL, buf, strlen (buf), 0);
     324           0 :       xfree (buf);
     325             :     }
     326             :   else
     327             :     {
     328           0 :       if (opt.with_colons)
     329           0 :         es_putc (':', fp);
     330             :       else
     331           0 :         tty_fprintf (fp, _("[not set]"));
     332             :     }
     333             : 
     334           0 :   if (opt.with_colons)
     335           0 :     es_fputs (":\n", fp);
     336             :   else
     337           0 :     tty_fprintf (fp, "\n");
     338           0 : }
     339             : 
     340             : /* Return true if the SHA1 fingerprint FPR consists only of zeroes. */
     341             : static int
     342           0 : fpr_is_zero (const char *fpr)
     343             : {
     344             :   int i;
     345             : 
     346           0 :   for (i=0; i < 20 && !fpr[i]; i++)
     347             :     ;
     348           0 :   return (i == 20);
     349             : }
     350             : 
     351             : 
     352             : /* Return true if the SHA1 fingerprint FPR consists only of 0xFF. */
     353             : static int
     354           0 : fpr_is_ff (const char *fpr)
     355             : {
     356             :   int i;
     357             : 
     358           0 :   for (i=0; i < 20 && fpr[i] == '\xff'; i++)
     359             :     ;
     360           0 :   return (i == 20);
     361             : }
     362             : 
     363             : 
     364             : /* Print all available information about the current card. */
     365             : void
     366           0 : card_status (estream_t fp, char *serialno, size_t serialnobuflen)
     367             : {
     368             :   struct agent_card_info_s info;
     369           0 :   PKT_public_key *pk = xcalloc (1, sizeof *pk);
     370           0 :   kbnode_t keyblock = NULL;
     371             :   int rc;
     372             :   unsigned int uval;
     373             :   const unsigned char *thefpr;
     374             :   int i;
     375             : 
     376           0 :   if (serialno && serialnobuflen)
     377           0 :     *serialno = 0;
     378             : 
     379           0 :   rc = agent_scd_learn (&info, 0);
     380           0 :   if (rc)
     381             :     {
     382           0 :       if (opt.with_colons)
     383           0 :         es_fputs ("AID:::\n", fp);
     384           0 :       log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (rc));
     385           0 :       xfree (pk);
     386           0 :       return;
     387             :     }
     388             : 
     389           0 :   if (opt.with_colons)
     390           0 :     es_fprintf (fp, "AID:%s:", info.serialno? info.serialno : "");
     391             :   else
     392           0 :     tty_fprintf (fp, "Application ID ...: %s\n",
     393           0 :                  info.serialno? info.serialno : "[none]");
     394           0 :   if (!info.serialno || strncmp (info.serialno, "D27600012401", 12)
     395           0 :       || strlen (info.serialno) != 32 )
     396             :     {
     397           0 :       if (info.apptype && !strcmp (info.apptype, "NKS"))
     398             :         {
     399           0 :           if (opt.with_colons)
     400           0 :             es_fputs ("netkey-card:\n", fp);
     401           0 :           log_info ("this is a NetKey card\n");
     402             :         }
     403           0 :       else if (info.apptype && !strcmp (info.apptype, "DINSIG"))
     404             :         {
     405           0 :           if (opt.with_colons)
     406           0 :             es_fputs ("dinsig-card:\n", fp);
     407           0 :           log_info ("this is a DINSIG compliant card\n");
     408             :         }
     409           0 :       else if (info.apptype && !strcmp (info.apptype, "P15"))
     410             :         {
     411           0 :           if (opt.with_colons)
     412           0 :             es_fputs ("pkcs15-card:\n", fp);
     413           0 :           log_info ("this is a PKCS#15 compliant card\n");
     414             :         }
     415           0 :       else if (info.apptype && !strcmp (info.apptype, "GELDKARTE"))
     416             :         {
     417           0 :           if (opt.with_colons)
     418           0 :             es_fputs ("geldkarte-card:\n", fp);
     419           0 :           log_info ("this is a Geldkarte compliant card\n");
     420             :         }
     421             :       else
     422             :         {
     423           0 :           if (opt.with_colons)
     424           0 :             es_fputs ("unknown:\n", fp);
     425             :         }
     426           0 :       log_info ("not an OpenPGP card\n");
     427           0 :       agent_release_card_info (&info);
     428           0 :       xfree (pk);
     429           0 :       return;
     430             :     }
     431             : 
     432           0 :   if (!serialno)
     433             :     ;
     434           0 :   else if (strlen (serialno)+1 > serialnobuflen)
     435           0 :     log_error ("serial number longer than expected\n");
     436             :   else
     437           0 :     strcpy (serialno, info.serialno);
     438             : 
     439           0 :   if (opt.with_colons)
     440           0 :     es_fputs ("openpgp-card:\n", fp);
     441             : 
     442             : 
     443           0 :   if (opt.with_colons)
     444             :     {
     445           0 :       es_fprintf (fp, "version:%.4s:\n", info.serialno+12);
     446           0 :       uval = xtoi_2(info.serialno+16)*256 + xtoi_2 (info.serialno+18);
     447           0 :       es_fprintf (fp, "vendor:%04x:%s:\n", uval, get_manufacturer (uval));
     448           0 :       es_fprintf (fp, "serial:%.8s:\n", info.serialno+20);
     449             : 
     450           0 :       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
     451             : 
     452           0 :       es_fputs ("lang:", fp);
     453           0 :       if (info.disp_lang)
     454           0 :         es_write_sanitized (fp, info.disp_lang, strlen (info.disp_lang),
     455             :                             ":", NULL);
     456           0 :       es_fputs (":\n", fp);
     457             : 
     458           0 :       es_fprintf (fp, "sex:%c:\n", (info.disp_sex == 1? 'm':
     459           0 :                                  info.disp_sex == 2? 'f' : 'u'));
     460             : 
     461           0 :       es_fputs ("url:", fp);
     462           0 :       if (info.pubkey_url)
     463           0 :         es_write_sanitized (fp, info.pubkey_url, strlen (info.pubkey_url),
     464             :                             ":", NULL);
     465           0 :       es_fputs (":\n", fp);
     466             : 
     467           0 :       es_fputs ("login:", fp);
     468           0 :       if (info.login_data)
     469           0 :         es_write_sanitized (fp, info.login_data, strlen (info.login_data),
     470             :                             ":", NULL);
     471           0 :       es_fputs (":\n", fp);
     472             : 
     473           0 :       es_fprintf (fp, "forcepin:%d:::\n", !info.chv1_cached);
     474           0 :       for (i=0; i < DIM (info.key_attr); i++)
     475           0 :         if (info.key_attr[0].algo == PUBKEY_ALGO_RSA)
     476           0 :           es_fprintf (fp, "keyattr:%d:%d:%u:\n", i+1,
     477             :                       info.key_attr[i].algo, info.key_attr[i].nbits);
     478           0 :         else if (info.key_attr[i].algo == PUBKEY_ALGO_ECDH
     479           0 :                  || info.key_attr[i].algo == PUBKEY_ALGO_ECDSA
     480           0 :                  || info.key_attr[i].algo == PUBKEY_ALGO_EDDSA)
     481           0 :           es_fprintf (fp, "keyattr:%d:%d:%s:\n", i+1,
     482             :                       info.key_attr[i].algo, info.key_attr[i].curve);
     483           0 :       es_fprintf (fp, "maxpinlen:%d:%d:%d:\n",
     484             :                   info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
     485           0 :       es_fprintf (fp, "pinretry:%d:%d:%d:\n",
     486             :                   info.chvretry[0], info.chvretry[1], info.chvretry[2]);
     487           0 :       es_fprintf (fp, "sigcount:%lu:::\n", info.sig_counter);
     488             : 
     489           0 :       for (i=0; i < 4; i++)
     490             :         {
     491           0 :           if (info.private_do[i])
     492             :             {
     493           0 :               es_fprintf (fp, "private_do:%d:", i+1);
     494           0 :               es_write_sanitized (fp, info.private_do[i],
     495           0 :                                   strlen (info.private_do[i]), ":", NULL);
     496           0 :               es_fputs (":\n", fp);
     497             :             }
     498             :         }
     499             : 
     500           0 :       es_fputs ("cafpr:", fp);
     501           0 :       print_sha1_fpr_colon (fp, info.cafpr1valid? info.cafpr1:NULL);
     502           0 :       print_sha1_fpr_colon (fp, info.cafpr2valid? info.cafpr2:NULL);
     503           0 :       print_sha1_fpr_colon (fp, info.cafpr3valid? info.cafpr3:NULL);
     504           0 :       es_putc ('\n', fp);
     505           0 :       es_fputs ("fpr:", fp);
     506           0 :       print_sha1_fpr_colon (fp, info.fpr1valid? info.fpr1:NULL);
     507           0 :       print_sha1_fpr_colon (fp, info.fpr2valid? info.fpr2:NULL);
     508           0 :       print_sha1_fpr_colon (fp, info.fpr3valid? info.fpr3:NULL);
     509           0 :       es_putc ('\n', fp);
     510           0 :       es_fprintf (fp, "fprtime:%lu:%lu:%lu:\n",
     511           0 :                (unsigned long)info.fpr1time, (unsigned long)info.fpr2time,
     512           0 :                (unsigned long)info.fpr3time);
     513             :     }
     514             :   else
     515             :     {
     516           0 :       tty_fprintf (fp, "Version ..........: %.1s%c.%.1s%c\n",
     517           0 :                    info.serialno[12] == '0'?"":info.serialno+12,
     518           0 :                    info.serialno[13],
     519           0 :                    info.serialno[14] == '0'?"":info.serialno+14,
     520           0 :                    info.serialno[15]);
     521           0 :       tty_fprintf (fp, "Manufacturer .....: %s\n",
     522           0 :                    get_manufacturer (xtoi_2(info.serialno+16)*256
     523           0 :                                      + xtoi_2 (info.serialno+18)));
     524           0 :       tty_fprintf (fp, "Serial number ....: %.8s\n", info.serialno+20);
     525             : 
     526           0 :       print_isoname (fp, "Name of cardholder: ", "name", info.disp_name);
     527           0 :       print_name (fp, "Language prefs ...: ", info.disp_lang);
     528           0 :       tty_fprintf (fp,    "Sex ..............: %s\n",
     529           0 :                    info.disp_sex == 1? _("male"):
     530           0 :                    info.disp_sex == 2? _("female") : _("unspecified"));
     531           0 :       print_name (fp, "URL of public key : ", info.pubkey_url);
     532           0 :       print_name (fp, "Login data .......: ", info.login_data);
     533           0 :       if (info.private_do[0])
     534           0 :         print_name (fp, "Private DO 1 .....: ", info.private_do[0]);
     535           0 :       if (info.private_do[1])
     536           0 :         print_name (fp, "Private DO 2 .....: ", info.private_do[1]);
     537           0 :       if (info.private_do[2])
     538           0 :         print_name (fp, "Private DO 3 .....: ", info.private_do[2]);
     539           0 :       if (info.private_do[3])
     540           0 :         print_name (fp, "Private DO 4 .....: ", info.private_do[3]);
     541           0 :       if (info.cafpr1valid)
     542             :         {
     543           0 :           tty_fprintf (fp, "CA fingerprint %d .:", 1);
     544           0 :           print_sha1_fpr (fp, info.cafpr1);
     545             :         }
     546           0 :       if (info.cafpr2valid)
     547             :         {
     548           0 :           tty_fprintf (fp, "CA fingerprint %d .:", 2);
     549           0 :           print_sha1_fpr (fp, info.cafpr2);
     550             :         }
     551           0 :       if (info.cafpr3valid)
     552             :         {
     553           0 :           tty_fprintf (fp, "CA fingerprint %d .:", 3);
     554           0 :           print_sha1_fpr (fp, info.cafpr3);
     555             :         }
     556           0 :       tty_fprintf (fp,    "Signature PIN ....: %s\n",
     557           0 :                    info.chv1_cached? _("not forced"): _("forced"));
     558           0 :       if (info.key_attr[0].algo)
     559             :         {
     560           0 :           tty_fprintf (fp,    "Key attributes ...:");
     561           0 :           for (i=0; i < DIM (info.key_attr); i++)
     562           0 :             if (info.key_attr[i].algo == PUBKEY_ALGO_RSA)
     563           0 :               tty_fprintf (fp, " rsa%u", info.key_attr[i].nbits);
     564           0 :             else if (info.key_attr[i].algo == PUBKEY_ALGO_ECDH
     565           0 :                      || info.key_attr[i].algo == PUBKEY_ALGO_ECDSA
     566           0 :                      || info.key_attr[i].algo == PUBKEY_ALGO_EDDSA)
     567           0 :               tty_fprintf (fp, " %s", info.key_attr[i].curve);
     568           0 :           tty_fprintf (fp, "\n");
     569             :         }
     570           0 :       tty_fprintf (fp,    "Max. PIN lengths .: %d %d %d\n",
     571             :                    info.chvmaxlen[0], info.chvmaxlen[1], info.chvmaxlen[2]);
     572           0 :       tty_fprintf (fp,    "PIN retry counter : %d %d %d\n",
     573             :                    info.chvretry[0], info.chvretry[1], info.chvretry[2]);
     574           0 :       tty_fprintf (fp,    "Signature counter : %lu\n", info.sig_counter);
     575           0 :       tty_fprintf (fp, "Signature key ....:");
     576           0 :       print_sha1_fpr (fp, info.fpr1valid? info.fpr1:NULL);
     577           0 :       if (info.fpr1valid && info.fpr1time)
     578           0 :         tty_fprintf (fp, "      created ....: %s\n",
     579             :                      isotimestamp (info.fpr1time));
     580           0 :       tty_fprintf (fp, "Encryption key....:");
     581           0 :       print_sha1_fpr (fp, info.fpr2valid? info.fpr2:NULL);
     582           0 :       if (info.fpr2valid && info.fpr2time)
     583           0 :         tty_fprintf (fp, "      created ....: %s\n",
     584             :                      isotimestamp (info.fpr2time));
     585           0 :       tty_fprintf (fp, "Authentication key:");
     586           0 :       print_sha1_fpr (fp, info.fpr3valid? info.fpr3:NULL);
     587           0 :       if (info.fpr3valid && info.fpr3time)
     588           0 :         tty_fprintf (fp, "      created ....: %s\n",
     589             :                      isotimestamp (info.fpr3time));
     590           0 :       tty_fprintf (fp, "General key info..: ");
     591             : 
     592           0 :       thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 :
     593           0 :                 info.fpr3valid? info.fpr3 : NULL);
     594             :       /* If the fingerprint is all 0xff, the key has no asssociated
     595             :          OpenPGP certificate.  */
     596           0 :       if ( thefpr && !fpr_is_ff (thefpr)
     597           0 :            && !get_pubkey_byfprint (pk, &keyblock, thefpr, 20))
     598             :         {
     599           0 :           print_pubkey_info (fp, pk);
     600           0 :           if (keyblock)
     601           0 :             print_card_key_info (fp, keyblock);
     602             :         }
     603             :       else
     604           0 :         tty_fprintf (fp, "[none]\n");
     605             :     }
     606             : 
     607           0 :   release_kbnode (keyblock);
     608           0 :   free_public_key (pk);
     609           0 :   agent_release_card_info (&info);
     610             : }
     611             : 
     612             : 
     613             : static char *
     614           0 : get_one_name (const char *prompt1, const char *prompt2)
     615             : {
     616             :   char *name;
     617             :   int i;
     618             : 
     619             :   for (;;)
     620             :     {
     621           0 :       name = cpr_get (prompt1, prompt2);
     622           0 :       if (!name)
     623           0 :         return NULL;
     624           0 :       trim_spaces (name);
     625           0 :       cpr_kill_prompt ();
     626           0 :       for (i=0; name[i] && name[i] >= ' ' && name[i] <= 126; i++)
     627             :         ;
     628             : 
     629             :       /* The name must be in Latin-1 and not UTF-8 - lacking the code
     630             :          to ensure this we restrict it to ASCII. */
     631           0 :       if (name[i])
     632           0 :         tty_printf (_("Error: Only plain ASCII is currently allowed.\n"));
     633           0 :       else if (strchr (name, '<'))
     634           0 :         tty_printf (_("Error: The \"<\" character may not be used.\n"));
     635           0 :       else if (strstr (name, "  "))
     636           0 :         tty_printf (_("Error: Double spaces are not allowed.\n"));
     637             :       else
     638           0 :         return name;
     639           0 :       xfree (name);
     640           0 :     }
     641             : }
     642             : 
     643             : 
     644             : 
     645             : static int
     646           0 : change_name (void)
     647             : {
     648           0 :   char *surname = NULL, *givenname = NULL;
     649             :   char *isoname, *p;
     650             :   int rc;
     651             : 
     652           0 :   surname = get_one_name ("keygen.smartcard.surname",
     653           0 :                                     _("Cardholder's surname: "));
     654           0 :   givenname = get_one_name ("keygen.smartcard.givenname",
     655           0 :                                        _("Cardholder's given name: "));
     656           0 :   if (!surname || !givenname || (!*surname && !*givenname))
     657             :     {
     658           0 :       xfree (surname);
     659           0 :       xfree (givenname);
     660           0 :       return -1; /*canceled*/
     661             :     }
     662             : 
     663           0 :   isoname = xmalloc ( strlen (surname) + 2 + strlen (givenname) + 1);
     664           0 :   strcpy (stpcpy (stpcpy (isoname, surname), "<<"), givenname);
     665           0 :   xfree (surname);
     666           0 :   xfree (givenname);
     667           0 :   for (p=isoname; *p; p++)
     668           0 :     if (*p == ' ')
     669           0 :       *p = '<';
     670             : 
     671           0 :   if (strlen (isoname) > 39 )
     672             :     {
     673           0 :       tty_printf (_("Error: Combined name too long "
     674             :                     "(limit is %d characters).\n"), 39);
     675           0 :       xfree (isoname);
     676           0 :       return -1;
     677             :     }
     678             : 
     679           0 :   rc = agent_scd_setattr ("DISP-NAME", isoname, strlen (isoname), NULL );
     680           0 :   if (rc)
     681           0 :     log_error ("error setting Name: %s\n", gpg_strerror (rc));
     682             : 
     683           0 :   xfree (isoname);
     684           0 :   return rc;
     685             : }
     686             : 
     687             : 
     688             : static int
     689           0 : change_url (void)
     690             : {
     691             :   char *url;
     692             :   int rc;
     693             : 
     694           0 :   url = cpr_get ("cardedit.change_url", _("URL to retrieve public key: "));
     695           0 :   if (!url)
     696           0 :     return -1;
     697           0 :   trim_spaces (url);
     698           0 :   cpr_kill_prompt ();
     699             : 
     700           0 :   if (strlen (url) > 254 )
     701             :     {
     702           0 :       tty_printf (_("Error: URL too long "
     703             :                     "(limit is %d characters).\n"), 254);
     704           0 :       xfree (url);
     705           0 :       return -1;
     706             :     }
     707             : 
     708           0 :   rc = agent_scd_setattr ("PUBKEY-URL", url, strlen (url), NULL );
     709           0 :   if (rc)
     710           0 :     log_error ("error setting URL: %s\n", gpg_strerror (rc));
     711           0 :   xfree (url);
     712           0 :   write_sc_op_status (rc);
     713           0 :   return rc;
     714             : }
     715             : 
     716             : 
     717             : /* Fetch the key from the URL given on the card or try to get it from
     718             :    the default keyserver.  */
     719             : static int
     720           0 : fetch_url (ctrl_t ctrl)
     721             : {
     722             :   int rc;
     723             :   struct agent_card_info_s info;
     724             : 
     725           0 :   memset(&info,0,sizeof(info));
     726             : 
     727           0 :   rc=agent_scd_getattr("PUBKEY-URL",&info);
     728           0 :   if(rc)
     729           0 :     log_error("error retrieving URL from card: %s\n",gpg_strerror(rc));
     730             :   else
     731             :     {
     732           0 :       struct keyserver_spec *spec=NULL;
     733             : 
     734           0 :       rc=agent_scd_getattr("KEY-FPR",&info);
     735           0 :       if(rc)
     736           0 :         log_error("error retrieving key fingerprint from card: %s\n",
     737             :                   gpg_strerror(rc));
     738           0 :       else if (info.pubkey_url && *info.pubkey_url)
     739             :         {
     740           0 :           spec = parse_keyserver_uri (info.pubkey_url, 1);
     741           0 :           if(spec && info.fpr1valid)
     742             :             {
     743             :               /* This is not perfectly right.  Currently, all card
     744             :                  fingerprints are 20 digits, but what about
     745             :                  fingerprints for a future v5 key?  We should get the
     746             :                  length from somewhere lower in the code.  In any
     747             :                  event, the fpr/keyid is not meaningful for straight
     748             :                  HTTP fetches, but using it allows the card to point
     749             :                  to HKP and LDAP servers as well. */
     750           0 :               rc = keyserver_import_fprint (ctrl, info.fpr1, 20, spec);
     751           0 :               free_keyserver_spec(spec);
     752             :             }
     753             :         }
     754           0 :       else if (info.fpr1valid)
     755             :         {
     756           0 :           rc = keyserver_import_fprint (ctrl, info.fpr1, 20, opt.keyserver);
     757             :         }
     758             :     }
     759             : 
     760           0 :   return rc;
     761             : }
     762             : 
     763             : 
     764             : /* Read data from file FNAME up to MAXLEN characters.  On error return
     765             :    -1 and store NULL at R_BUFFER; on success return the number of
     766             :    bytes read and store the address of a newly allocated buffer at
     767             :    R_BUFFER. */
     768             : static int
     769           0 : get_data_from_file (const char *fname, size_t maxlen, char **r_buffer)
     770             : {
     771             :   estream_t fp;
     772             :   char *data;
     773             :   int n;
     774             : 
     775           0 :   *r_buffer = NULL;
     776             : 
     777           0 :   fp = es_fopen (fname, "rb");
     778             : #if GNUPG_MAJOR_VERSION == 1
     779             :   if (fp && is_secured_file (fileno (fp)))
     780             :     {
     781             :       fclose (fp);
     782             :       fp = NULL;
     783             :       errno = EPERM;
     784             :     }
     785             : #endif
     786           0 :   if (!fp)
     787             :     {
     788           0 :       tty_printf (_("can't open '%s': %s\n"), fname, strerror (errno));
     789           0 :       return -1;
     790             :     }
     791             : 
     792           0 :   data = xtrymalloc (maxlen? maxlen:1);
     793           0 :   if (!data)
     794             :     {
     795           0 :       tty_printf (_("error allocating enough memory: %s\n"), strerror (errno));
     796           0 :       es_fclose (fp);
     797           0 :       return -1;
     798             :     }
     799             : 
     800           0 :   if (maxlen)
     801           0 :     n = es_fread (data, 1, maxlen, fp);
     802             :   else
     803           0 :     n = 0;
     804           0 :   es_fclose (fp);
     805           0 :   if (n < 0)
     806             :     {
     807           0 :       tty_printf (_("error reading '%s': %s\n"), fname, strerror (errno));
     808           0 :       xfree (data);
     809           0 :       return -1;
     810             :     }
     811           0 :   *r_buffer = data;
     812           0 :   return n;
     813             : }
     814             : 
     815             : 
     816             : /* Write LENGTH bytes from BUFFER to file FNAME.  Return 0 on
     817             :    success.  */
     818             : static int
     819           0 : put_data_to_file (const char *fname, const void *buffer, size_t length)
     820             : {
     821             :   estream_t fp;
     822             : 
     823           0 :   fp = es_fopen (fname, "wb");
     824             : #if GNUPG_MAJOR_VERSION == 1
     825             :   if (fp && is_secured_file (fileno (fp)))
     826             :     {
     827             :       fclose (fp);
     828             :       fp = NULL;
     829             :       errno = EPERM;
     830             :     }
     831             : #endif
     832           0 :   if (!fp)
     833             :     {
     834           0 :       tty_printf (_("can't create '%s': %s\n"), fname, strerror (errno));
     835           0 :       return -1;
     836             :     }
     837             : 
     838           0 :   if (length && es_fwrite (buffer, length, 1, fp) != 1)
     839             :     {
     840           0 :       tty_printf (_("error writing '%s': %s\n"), fname, strerror (errno));
     841           0 :       es_fclose (fp);
     842           0 :       return -1;
     843             :     }
     844           0 :   es_fclose (fp);
     845           0 :   return 0;
     846             : }
     847             : 
     848             : 
     849             : static int
     850           0 : change_login (const char *args)
     851             : {
     852             :   char *data;
     853             :   int n;
     854             :   int rc;
     855             : 
     856           0 :   if (args && *args == '<')  /* Read it from a file */
     857             :     {
     858           0 :       for (args++; spacep (args); args++)
     859             :         ;
     860           0 :       n = get_data_from_file (args, 254, &data);
     861           0 :       if (n < 0)
     862           0 :         return -1;
     863             :     }
     864             :   else
     865             :     {
     866           0 :       data = cpr_get ("cardedit.change_login",
     867           0 :                       _("Login data (account name): "));
     868           0 :       if (!data)
     869           0 :         return -1;
     870           0 :       trim_spaces (data);
     871           0 :       cpr_kill_prompt ();
     872           0 :       n = strlen (data);
     873             :     }
     874             : 
     875           0 :   if (n > 254 )
     876             :     {
     877           0 :       tty_printf (_("Error: Login data too long "
     878             :                     "(limit is %d characters).\n"), 254);
     879           0 :       xfree (data);
     880           0 :       return -1;
     881             :     }
     882             : 
     883           0 :   rc = agent_scd_setattr ("LOGIN-DATA", data, n, NULL );
     884           0 :   if (rc)
     885           0 :     log_error ("error setting login data: %s\n", gpg_strerror (rc));
     886           0 :   xfree (data);
     887           0 :   write_sc_op_status (rc);
     888           0 :   return rc;
     889             : }
     890             : 
     891             : static int
     892           0 : change_private_do (const char *args, int nr)
     893             : {
     894           0 :   char do_name[] = "PRIVATE-DO-X";
     895             :   char *data;
     896             :   int n;
     897             :   int rc;
     898             : 
     899           0 :   assert (nr >= 1 && nr <= 4);
     900           0 :   do_name[11] = '0' + nr;
     901             : 
     902           0 :   if (args && (args = strchr (args, '<')))  /* Read it from a file */
     903             :     {
     904           0 :       for (args++; spacep (args); args++)
     905             :         ;
     906           0 :       n = get_data_from_file (args, 254, &data);
     907           0 :       if (n < 0)
     908           0 :         return -1;
     909             :     }
     910             :   else
     911             :     {
     912           0 :       data = cpr_get ("cardedit.change_private_do",
     913           0 :                       _("Private DO data: "));
     914           0 :       if (!data)
     915           0 :         return -1;
     916           0 :       trim_spaces (data);
     917           0 :       cpr_kill_prompt ();
     918           0 :       n = strlen (data);
     919             :     }
     920             : 
     921           0 :   if (n > 254 )
     922             :     {
     923           0 :       tty_printf (_("Error: Private DO too long "
     924             :                     "(limit is %d characters).\n"), 254);
     925           0 :       xfree (data);
     926           0 :       return -1;
     927             :     }
     928             : 
     929           0 :   rc = agent_scd_setattr (do_name, data, n, NULL );
     930           0 :   if (rc)
     931           0 :     log_error ("error setting private DO: %s\n", gpg_strerror (rc));
     932           0 :   xfree (data);
     933           0 :   write_sc_op_status (rc);
     934           0 :   return rc;
     935             : }
     936             : 
     937             : 
     938             : static int
     939           0 : change_cert (const char *args)
     940             : {
     941             :   char *data;
     942             :   int n;
     943             :   int rc;
     944             : 
     945           0 :   if (args && *args == '<')  /* Read it from a file */
     946             :     {
     947           0 :       for (args++; spacep (args); args++)
     948             :         ;
     949           0 :       n = get_data_from_file (args, 16384, &data);
     950           0 :       if (n < 0)
     951           0 :         return -1;
     952             :     }
     953             :   else
     954             :     {
     955           0 :       tty_printf ("usage error: redirection to file required\n");
     956           0 :       return -1;
     957             :     }
     958             : 
     959           0 :   rc = agent_scd_writecert ("OPENPGP.3", data, n);
     960           0 :   if (rc)
     961           0 :     log_error ("error writing certificate to card: %s\n", gpg_strerror (rc));
     962           0 :   xfree (data);
     963           0 :   write_sc_op_status (rc);
     964           0 :   return rc;
     965             : }
     966             : 
     967             : 
     968             : static int
     969           0 : read_cert (const char *args)
     970             : {
     971             :   const char *fname;
     972             :   void *buffer;
     973             :   size_t length;
     974             :   int rc;
     975             : 
     976           0 :   if (args && *args == '>')  /* Write it to a file */
     977             :     {
     978           0 :       for (args++; spacep (args); args++)
     979             :         ;
     980           0 :       fname = args;
     981             :     }
     982             :   else
     983             :     {
     984           0 :       tty_printf ("usage error: redirection to file required\n");
     985           0 :       return -1;
     986             :     }
     987             : 
     988           0 :   rc = agent_scd_readcert ("OPENPGP.3", &buffer, &length);
     989           0 :   if (rc)
     990           0 :     log_error ("error reading certificate from card: %s\n", gpg_strerror (rc));
     991             :   else
     992           0 :     rc = put_data_to_file (fname, buffer, length);
     993           0 :   xfree (buffer);
     994           0 :   write_sc_op_status (rc);
     995           0 :   return rc;
     996             : }
     997             : 
     998             : 
     999             : static int
    1000           0 : change_lang (void)
    1001             : {
    1002             :   char *data, *p;
    1003             :   int rc;
    1004             : 
    1005           0 :   data = cpr_get ("cardedit.change_lang",
    1006           0 :                   _("Language preferences: "));
    1007           0 :   if (!data)
    1008           0 :     return -1;
    1009           0 :   trim_spaces (data);
    1010           0 :   cpr_kill_prompt ();
    1011             : 
    1012           0 :   if (strlen (data) > 8 || (strlen (data) & 1))
    1013             :     {
    1014           0 :       tty_printf (_("Error: invalid length of preference string.\n"));
    1015           0 :       xfree (data);
    1016           0 :       return -1;
    1017             :     }
    1018             : 
    1019           0 :   for (p=data; *p && *p >= 'a' && *p <= 'z'; p++)
    1020             :     ;
    1021           0 :   if (*p)
    1022             :     {
    1023           0 :       tty_printf (_("Error: invalid characters in preference string.\n"));
    1024           0 :       xfree (data);
    1025           0 :       return -1;
    1026             :     }
    1027             : 
    1028           0 :   rc = agent_scd_setattr ("DISP-LANG", data, strlen (data), NULL );
    1029           0 :   if (rc)
    1030           0 :     log_error ("error setting lang: %s\n", gpg_strerror (rc));
    1031           0 :   xfree (data);
    1032           0 :   write_sc_op_status (rc);
    1033           0 :   return rc;
    1034             : }
    1035             : 
    1036             : 
    1037             : static int
    1038           0 : change_sex (void)
    1039             : {
    1040             :   char *data;
    1041             :   const char *str;
    1042             :   int rc;
    1043             : 
    1044           0 :   data = cpr_get ("cardedit.change_sex",
    1045           0 :                   _("Sex ((M)ale, (F)emale or space): "));
    1046           0 :   if (!data)
    1047           0 :     return -1;
    1048           0 :   trim_spaces (data);
    1049           0 :   cpr_kill_prompt ();
    1050             : 
    1051           0 :   if (!*data)
    1052           0 :     str = "9";
    1053           0 :   else if ((*data == 'M' || *data == 'm') && !data[1])
    1054           0 :     str = "1";
    1055           0 :   else if ((*data == 'F' || *data == 'f') && !data[1])
    1056           0 :     str = "2";
    1057             :   else
    1058             :     {
    1059           0 :       tty_printf (_("Error: invalid response.\n"));
    1060           0 :       xfree (data);
    1061           0 :       return -1;
    1062             :     }
    1063             : 
    1064           0 :   rc = agent_scd_setattr ("DISP-SEX", str, 1, NULL );
    1065           0 :   if (rc)
    1066           0 :     log_error ("error setting sex: %s\n", gpg_strerror (rc));
    1067           0 :   xfree (data);
    1068           0 :   write_sc_op_status (rc);
    1069           0 :   return rc;
    1070             : }
    1071             : 
    1072             : 
    1073             : static int
    1074           0 : change_cafpr (int fprno)
    1075             : {
    1076             :   char *data;
    1077             :   const char *s;
    1078             :   int i, c, rc;
    1079             :   unsigned char fpr[20];
    1080             : 
    1081           0 :   data = cpr_get ("cardedit.change_cafpr", _("CA fingerprint: "));
    1082           0 :   if (!data)
    1083           0 :     return -1;
    1084           0 :   trim_spaces (data);
    1085           0 :   cpr_kill_prompt ();
    1086             : 
    1087           0 :   for (i=0, s=data; i < 20 && *s; )
    1088             :     {
    1089           0 :       while (spacep(s))
    1090           0 :         s++;
    1091           0 :       if (*s == ':')
    1092           0 :         s++;
    1093           0 :       while (spacep(s))
    1094           0 :         s++;
    1095           0 :       c = hextobyte (s);
    1096           0 :       if (c == -1)
    1097           0 :         break;
    1098           0 :       fpr[i++] = c;
    1099           0 :       s += 2;
    1100             :     }
    1101           0 :   xfree (data);
    1102           0 :   if (i != 20 || *s)
    1103             :     {
    1104           0 :       tty_printf (_("Error: invalid formatted fingerprint.\n"));
    1105           0 :       return -1;
    1106             :     }
    1107             : 
    1108           0 :   rc = agent_scd_setattr (fprno==1?"CA-FPR-1":
    1109             :                           fprno==2?"CA-FPR-2":
    1110             :                           fprno==3?"CA-FPR-3":"x", fpr, 20, NULL );
    1111           0 :   if (rc)
    1112           0 :     log_error ("error setting cafpr: %s\n", gpg_strerror (rc));
    1113           0 :   write_sc_op_status (rc);
    1114           0 :   return rc;
    1115             : }
    1116             : 
    1117             : 
    1118             : 
    1119             : static void
    1120           0 : toggle_forcesig (void)
    1121             : {
    1122             :   struct agent_card_info_s info;
    1123             :   int rc;
    1124             :   int newstate;
    1125             : 
    1126           0 :   memset (&info, 0, sizeof info);
    1127           0 :   rc = agent_scd_getattr ("CHV-STATUS", &info);
    1128           0 :   if (rc)
    1129             :     {
    1130           0 :       log_error ("error getting current status: %s\n", gpg_strerror (rc));
    1131           0 :       return;
    1132             :     }
    1133           0 :   newstate = !info.chv1_cached;
    1134           0 :   agent_release_card_info (&info);
    1135             : 
    1136           0 :   rc = agent_scd_setattr ("CHV-STATUS-1", newstate? "\x01":"", 1, NULL);
    1137           0 :   if (rc)
    1138           0 :     log_error ("error toggling signature PIN flag: %s\n", gpg_strerror (rc));
    1139           0 :   write_sc_op_status (rc);
    1140             : }
    1141             : 
    1142             : 
    1143             : /* Helper for the key generation/edit functions.  */
    1144             : static int
    1145           0 : get_info_for_key_operation (struct agent_card_info_s *info)
    1146             : {
    1147             :   int rc;
    1148             : 
    1149           0 :   memset (info, 0, sizeof *info);
    1150           0 :   rc = agent_scd_getattr ("SERIALNO", info);
    1151           0 :   if (rc || !info->serialno || strncmp (info->serialno, "D27600012401", 12)
    1152           0 :       || strlen (info->serialno) != 32 )
    1153             :     {
    1154           0 :       log_error (_("key operation not possible: %s\n"),
    1155           0 :                  rc ? gpg_strerror (rc) : _("not an OpenPGP card"));
    1156           0 :       return rc? rc: -1;
    1157             :     }
    1158           0 :   rc = agent_scd_getattr ("KEY-FPR", info);
    1159           0 :   if (!rc)
    1160           0 :     rc = agent_scd_getattr ("CHV-STATUS", info);
    1161           0 :   if (!rc)
    1162           0 :     rc = agent_scd_getattr ("DISP-NAME", info);
    1163           0 :   if (!rc)
    1164           0 :     rc = agent_scd_getattr ("EXTCAP", info);
    1165           0 :   if (!rc)
    1166           0 :     rc = agent_scd_getattr ("KEY-ATTR", info);
    1167           0 :   if (rc)
    1168           0 :     log_error (_("error getting current key info: %s\n"), gpg_strerror (rc));
    1169           0 :   return rc;
    1170             : }
    1171             : 
    1172             : 
    1173             : /* Helper for the key generation/edit functions.  */
    1174             : static int
    1175           0 : check_pin_for_key_operation (struct agent_card_info_s *info, int *forced_chv1)
    1176             : {
    1177           0 :   int rc = 0;
    1178             : 
    1179           0 :   agent_clear_pin_cache (info->serialno);
    1180             : 
    1181           0 :   *forced_chv1 = !info->chv1_cached;
    1182           0 :   if (*forced_chv1)
    1183             :     { /* Switch off the forced mode so that during key generation we
    1184             :          don't get bothered with PIN queries for each
    1185             :          self-signature. */
    1186           0 :       rc = agent_scd_setattr ("CHV-STATUS-1", "\x01", 1, info->serialno);
    1187           0 :       if (rc)
    1188             :         {
    1189           0 :           log_error ("error clearing forced signature PIN flag: %s\n",
    1190             :                      gpg_strerror (rc));
    1191           0 :           *forced_chv1 = 0;
    1192             :         }
    1193             :     }
    1194             : 
    1195           0 :   if (!rc)
    1196             :     {
    1197             :       /* Check the PIN now, so that we won't get asked later for each
    1198             :          binding signature. */
    1199           0 :       rc = agent_scd_checkpin (info->serialno);
    1200           0 :       if (rc)
    1201             :         {
    1202           0 :           log_error ("error checking the PIN: %s\n", gpg_strerror (rc));
    1203           0 :           write_sc_op_status (rc);
    1204             :         }
    1205             :   }
    1206           0 :   return rc;
    1207             : }
    1208             : 
    1209             : /* Helper for the key generation/edit functions.  */
    1210             : static void
    1211           0 : restore_forced_chv1 (int *forced_chv1)
    1212             : {
    1213             :   int rc;
    1214             : 
    1215           0 :   if (*forced_chv1)
    1216             :     { /* Switch back to forced state. */
    1217           0 :       rc = agent_scd_setattr ("CHV-STATUS-1", "", 1, NULL);
    1218           0 :       if (rc)
    1219             :         {
    1220           0 :           log_error ("error setting forced signature PIN flag: %s\n",
    1221             :                      gpg_strerror (rc));
    1222             :         }
    1223             :     }
    1224           0 : }
    1225             : 
    1226             : 
    1227             : /* Helper for the key generation/edit functions.  */
    1228             : static void
    1229           0 : show_card_key_info (struct agent_card_info_s *info)
    1230             : {
    1231           0 :   tty_fprintf (NULL, "Signature key ....:");
    1232           0 :   print_sha1_fpr (NULL, info->fpr1valid? info->fpr1:NULL);
    1233           0 :   tty_fprintf (NULL, "Encryption key....:");
    1234           0 :   print_sha1_fpr (NULL, info->fpr2valid? info->fpr2:NULL);
    1235           0 :   tty_fprintf (NULL, "Authentication key:");
    1236           0 :   print_sha1_fpr (NULL, info->fpr3valid? info->fpr3:NULL);
    1237           0 :   tty_printf ("\n");
    1238           0 : }
    1239             : 
    1240             : 
    1241             : /* Helper for the key generation/edit functions.  */
    1242             : static int
    1243           0 : replace_existing_key_p (struct agent_card_info_s *info, int keyno)
    1244             : {
    1245           0 :   assert (keyno >= 0 && keyno <= 3);
    1246             : 
    1247           0 :   if ((keyno == 1 && info->fpr1valid)
    1248           0 :       || (keyno == 2 && info->fpr2valid)
    1249           0 :       || (keyno == 3 && info->fpr3valid))
    1250             :     {
    1251           0 :       tty_printf ("\n");
    1252           0 :       log_info ("WARNING: such a key has already been stored on the card!\n");
    1253           0 :       tty_printf ("\n");
    1254           0 :       if ( !cpr_get_answer_is_yes( "cardedit.genkeys.replace_key",
    1255           0 :                                   _("Replace existing key? (y/N) ")))
    1256           0 :         return -1;
    1257           0 :       return 1;
    1258             :     }
    1259           0 :   return 0;
    1260             : }
    1261             : 
    1262             : 
    1263             : static void
    1264           0 : show_keysize_warning (void)
    1265             : {
    1266             :   static int shown;
    1267             : 
    1268           0 :   if (shown)
    1269           0 :     return;
    1270           0 :   shown = 1;
    1271           0 :   tty_printf
    1272           0 :     (_("Note: There is no guarantee that the card "
    1273             :        "supports the requested size.\n"
    1274             :        "      If the key generation does not succeed, "
    1275             :        "please check the\n"
    1276             :        "      documentation of your card to see what "
    1277             :        "sizes are allowed.\n"));
    1278             : }
    1279             : 
    1280             : 
    1281             : /* Ask for the size of a card key.  NBITS is the current size
    1282             :    configured for the card.  KEYNO is the number of the key used to
    1283             :    select the prompt.  Returns 0 to use the default size (i.e. NBITS)
    1284             :    or the selected size.  */
    1285             : static unsigned int
    1286           0 : ask_card_keysize (int keyno, unsigned int nbits)
    1287             : {
    1288           0 :   unsigned int min_nbits = 1024;
    1289           0 :   unsigned int max_nbits = 4096;
    1290             :   char *prompt, *answer;
    1291             :   unsigned int req_nbits;
    1292             : 
    1293             :   for (;;)
    1294             :     {
    1295           0 :       prompt = xasprintf
    1296             :         (keyno == 0?
    1297             :          _("What keysize do you want for the Signature key? (%u) "):
    1298             :          keyno == 1?
    1299             :          _("What keysize do you want for the Encryption key? (%u) "):
    1300             :          _("What keysize do you want for the Authentication key? (%u) "),
    1301             :          nbits);
    1302           0 :       answer = cpr_get ("cardedit.genkeys.size", prompt);
    1303           0 :       cpr_kill_prompt ();
    1304           0 :       req_nbits = *answer? atoi (answer): nbits;
    1305           0 :       xfree (prompt);
    1306           0 :       xfree (answer);
    1307             : 
    1308           0 :       if (req_nbits != nbits && (req_nbits % 32) )
    1309             :         {
    1310           0 :           req_nbits = ((req_nbits + 31) / 32) * 32;
    1311           0 :           tty_printf (_("rounded up to %u bits\n"), req_nbits);
    1312             :         }
    1313             : 
    1314           0 :       if (req_nbits == nbits)
    1315           0 :         return 0;  /* Use default.  */
    1316             : 
    1317           0 :       if (req_nbits < min_nbits || req_nbits > max_nbits)
    1318             :         {
    1319           0 :           tty_printf (_("%s keysizes must be in the range %u-%u\n"),
    1320             :                       "RSA", min_nbits, max_nbits);
    1321             :         }
    1322             :       else
    1323             :         {
    1324           0 :           tty_printf (_("The card will now be re-configured "
    1325             :                         "to generate a key of %u bits\n"), req_nbits);
    1326           0 :           show_keysize_warning ();
    1327           0 :           return req_nbits;
    1328             :         }
    1329           0 :     }
    1330             : }
    1331             : 
    1332             : 
    1333             : /* Change the size of key KEYNO (0..2) to NBITS and show an error
    1334             :    message if that fails.  */
    1335             : static gpg_error_t
    1336           0 : do_change_keysize (int keyno, unsigned int nbits)
    1337             : {
    1338             :   gpg_error_t err;
    1339             :   char args[100];
    1340             : 
    1341           0 :   snprintf (args, sizeof args, "--force %d 1 rsa%u", keyno+1, nbits);
    1342           0 :   err = agent_scd_setattr ("KEY-ATTR", args, strlen (args), NULL);
    1343           0 :   if (err)
    1344           0 :     log_error (_("error changing size of key %d to %u bits: %s\n"),
    1345             :                keyno+1, nbits, gpg_strerror (err));
    1346           0 :   return err;
    1347             : }
    1348             : 
    1349             : 
    1350             : static void
    1351           0 : generate_card_keys (ctrl_t ctrl)
    1352             : {
    1353             :   struct agent_card_info_s info;
    1354             :   int forced_chv1;
    1355             :   int want_backup;
    1356             :   int keyno;
    1357             : 
    1358           0 :   if (get_info_for_key_operation (&info))
    1359           0 :     return;
    1360             : 
    1361           0 :   if (info.extcap.ki)
    1362             :     {
    1363             :       char *answer;
    1364             : 
    1365             :       /* FIXME: Should be something like cpr_get_bool so that a status
    1366             :          GET_BOOL will be emitted.  */
    1367           0 :       answer = cpr_get ("cardedit.genkeys.backup_enc",
    1368           0 :                         _("Make off-card backup of encryption key? (Y/n) "));
    1369             : 
    1370           0 :       want_backup = answer_is_yes_no_default (answer, 1/*(default to Yes)*/);
    1371           0 :       cpr_kill_prompt ();
    1372           0 :       xfree (answer);
    1373             :     }
    1374             :   else
    1375           0 :     want_backup = 0;
    1376             : 
    1377           0 :   if ( (info.fpr1valid && !fpr_is_zero (info.fpr1))
    1378           0 :        || (info.fpr2valid && !fpr_is_zero (info.fpr2))
    1379           0 :        || (info.fpr3valid && !fpr_is_zero (info.fpr3)))
    1380             :     {
    1381           0 :       tty_printf ("\n");
    1382           0 :       log_info (_("Note: keys are already stored on the card!\n"));
    1383           0 :       tty_printf ("\n");
    1384           0 :       if ( !cpr_get_answer_is_yes ("cardedit.genkeys.replace_keys",
    1385           0 :                                    _("Replace existing keys? (y/N) ")))
    1386             :         {
    1387           0 :           agent_release_card_info (&info);
    1388           0 :           return;
    1389             :         }
    1390             :     }
    1391             : 
    1392             :   /* If no displayed name has been set, we assume that this is a fresh
    1393             :      card and print a hint about the default PINs.  */
    1394           0 :   if (!info.disp_name || !*info.disp_name)
    1395             :     {
    1396           0 :       tty_printf ("\n");
    1397           0 :       tty_printf (_("Please note that the factory settings of the PINs are\n"
    1398             :                     "   PIN = '%s'     Admin PIN = '%s'\n"
    1399             :                     "You should change them using the command --change-pin\n"),
    1400             :                   "123456", "12345678");
    1401           0 :       tty_printf ("\n");
    1402             :     }
    1403             : 
    1404           0 :   if (check_pin_for_key_operation (&info, &forced_chv1))
    1405           0 :     goto leave;
    1406             : 
    1407             :   /* If the cards features changeable key attributes, we ask for the
    1408             :      key size.  */
    1409           0 :   if (info.is_v2 && info.extcap.aac)
    1410             :     {
    1411             :       unsigned int nbits;
    1412             : 
    1413           0 :       for (keyno = 0; keyno < DIM (info.key_attr); keyno++)
    1414             :         {
    1415           0 :           nbits = ask_card_keysize (keyno, info.key_attr[keyno].nbits);
    1416           0 :           if (nbits && do_change_keysize (keyno, nbits))
    1417             :             {
    1418             :               /* Error: Better read the default key size again.  */
    1419           0 :               agent_release_card_info (&info);
    1420           0 :               if (get_info_for_key_operation (&info))
    1421           0 :                 goto leave;
    1422             :               /* Ask again for this key size. */
    1423           0 :               keyno--;
    1424             :             }
    1425             :         }
    1426             :       /* Note that INFO has not be synced.  However we will only use
    1427             :          the serialnumber and thus it won't harm.  */
    1428             :     }
    1429             : 
    1430           0 :   generate_keypair (ctrl, 1, NULL, info.serialno, want_backup);
    1431             : 
    1432             :  leave:
    1433           0 :   agent_release_card_info (&info);
    1434           0 :   restore_forced_chv1 (&forced_chv1);
    1435             : }
    1436             : 
    1437             : 
    1438             : /* This function is used by the key edit menu to generate an arbitrary
    1439             :    subkey. */
    1440             : gpg_error_t
    1441           0 : card_generate_subkey (KBNODE pub_keyblock)
    1442             : {
    1443             :   gpg_error_t err;
    1444             :   struct agent_card_info_s info;
    1445           0 :   int forced_chv1 = 0;
    1446             :   int keyno;
    1447             : 
    1448           0 :   err = get_info_for_key_operation (&info);
    1449           0 :   if (err)
    1450           0 :     return err;
    1451             : 
    1452           0 :   show_card_key_info (&info);
    1453             : 
    1454           0 :   tty_printf (_("Please select the type of key to generate:\n"));
    1455             : 
    1456           0 :   tty_printf (_("   (1) Signature key\n"));
    1457           0 :   tty_printf (_("   (2) Encryption key\n"));
    1458           0 :   tty_printf (_("   (3) Authentication key\n"));
    1459             : 
    1460             :   for (;;)
    1461             :     {
    1462           0 :       char *answer = cpr_get ("cardedit.genkeys.subkeytype",
    1463           0 :                               _("Your selection? "));
    1464           0 :       cpr_kill_prompt();
    1465           0 :       if (*answer == CONTROL_D)
    1466             :         {
    1467           0 :           xfree (answer);
    1468           0 :           err = gpg_error (GPG_ERR_CANCELED);
    1469           0 :           goto leave;
    1470             :         }
    1471           0 :       keyno = *answer? atoi(answer): 0;
    1472           0 :       xfree(answer);
    1473           0 :       if (keyno >= 1 && keyno <= 3)
    1474           0 :         break; /* Okay. */
    1475           0 :       tty_printf(_("Invalid selection.\n"));
    1476           0 :     }
    1477             : 
    1478           0 :   if (replace_existing_key_p (&info, keyno) < 0)
    1479             :     {
    1480           0 :       err = gpg_error (GPG_ERR_CANCELED);
    1481           0 :       goto leave;
    1482             :     }
    1483             : 
    1484           0 :   err = check_pin_for_key_operation (&info, &forced_chv1);
    1485           0 :   if (err)
    1486           0 :     goto leave;
    1487             : 
    1488             :   /* If the cards features changeable key attributes, we ask for the
    1489             :      key size.  */
    1490           0 :   if (info.is_v2 && info.extcap.aac)
    1491             :     {
    1492             :       unsigned int nbits;
    1493             : 
    1494             :     ask_again:
    1495           0 :       nbits = ask_card_keysize (keyno-1, info.key_attr[keyno-1].nbits);
    1496           0 :       if (nbits && do_change_keysize (keyno-1, nbits))
    1497             :         {
    1498             :           /* Error: Better read the default key size again.  */
    1499           0 :           agent_release_card_info (&info);
    1500           0 :           err = get_info_for_key_operation (&info);
    1501           0 :           if (err)
    1502           0 :             goto leave;
    1503           0 :           goto ask_again;
    1504             :         }
    1505             :       /* Note that INFO has not be synced.  However we will only use
    1506             :          the serialnumber and thus it won't harm.  */
    1507             :     }
    1508             : 
    1509           0 :   err = generate_card_subkeypair (pub_keyblock, keyno, info.serialno);
    1510             : 
    1511             :  leave:
    1512           0 :   agent_release_card_info (&info);
    1513           0 :   restore_forced_chv1 (&forced_chv1);
    1514           0 :   return err;
    1515             : }
    1516             : 
    1517             : 
    1518             : /* Store the key at NODE into the smartcard and modify NODE to
    1519             :    carry the serialno stuff instead of the actual secret key
    1520             :    parameters.  USE is the usage for that key; 0 means any
    1521             :    usage. */
    1522             : int
    1523           0 : card_store_subkey (KBNODE node, int use)
    1524             : {
    1525             :   struct agent_card_info_s info;
    1526           0 :   int okay = 0;
    1527             :   unsigned int nbits;
    1528             :   int allow_keyno[3];
    1529             :   int  keyno;
    1530             :   PKT_public_key *pk;
    1531             :   gpg_error_t err;
    1532             :   char *hexgrip;
    1533             :   int rc;
    1534             :   gnupg_isotime_t timebuf;
    1535             : 
    1536           0 :   assert (node->pkt->pkttype == PKT_PUBLIC_KEY
    1537             :           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY);
    1538             : 
    1539           0 :   pk = node->pkt->pkt.public_key;
    1540             : 
    1541           0 :   if (get_info_for_key_operation (&info))
    1542           0 :     return 0;
    1543             : 
    1544           0 :   if (!info.extcap.ki)
    1545             :     {
    1546           0 :       tty_printf ("The card does not support the import of keys\n");
    1547           0 :       tty_printf ("\n");
    1548           0 :       goto leave;
    1549             :     }
    1550             : 
    1551           0 :   nbits = nbits_from_pk (pk);
    1552             : 
    1553           0 :   if (!info.is_v2 && nbits != 1024)
    1554             :     {
    1555           0 :       tty_printf ("You may only store a 1024 bit RSA key on the card\n");
    1556           0 :       tty_printf ("\n");
    1557           0 :       goto leave;
    1558             :     }
    1559             : 
    1560           0 :   allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_CERT)));
    1561           0 :   allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC)));
    1562           0 :   allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)));
    1563             : 
    1564           0 :   tty_printf (_("Please select where to store the key:\n"));
    1565             : 
    1566           0 :   if (allow_keyno[0])
    1567           0 :     tty_printf (_("   (1) Signature key\n"));
    1568           0 :   if (allow_keyno[1])
    1569           0 :     tty_printf (_("   (2) Encryption key\n"));
    1570           0 :   if (allow_keyno[2])
    1571           0 :     tty_printf (_("   (3) Authentication key\n"));
    1572             : 
    1573             :   for (;;)
    1574             :     {
    1575           0 :       char *answer = cpr_get ("cardedit.genkeys.storekeytype",
    1576           0 :                               _("Your selection? "));
    1577           0 :       cpr_kill_prompt();
    1578           0 :       if (*answer == CONTROL_D || !*answer)
    1579             :         {
    1580           0 :           xfree (answer);
    1581           0 :           goto leave;
    1582             :         }
    1583           0 :       keyno = *answer? atoi(answer): 0;
    1584           0 :       xfree(answer);
    1585           0 :       if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1])
    1586             :         {
    1587           0 :           if (info.is_v2 && !info.extcap.aac
    1588           0 :               && info.key_attr[keyno-1].nbits != nbits)
    1589             :             {
    1590           0 :               tty_printf ("Key does not match the card's capability.\n");
    1591             :             }
    1592             :           else
    1593             :             break; /* Okay. */
    1594             :         }
    1595             :       else
    1596           0 :         tty_printf(_("Invalid selection.\n"));
    1597           0 :     }
    1598             : 
    1599           0 :   if ((rc = replace_existing_key_p (&info, keyno)) < 0)
    1600           0 :     goto leave;
    1601             : 
    1602           0 :   err = hexkeygrip_from_pk (pk, &hexgrip);
    1603           0 :   if (err)
    1604           0 :     goto leave;
    1605             : 
    1606           0 :   epoch2isotime (timebuf, (time_t)pk->timestamp);
    1607           0 :   rc = agent_keytocard (hexgrip, keyno, rc, info.serialno, timebuf);
    1608             : 
    1609           0 :   if (rc)
    1610           0 :     log_error (_("KEYTOCARD failed: %s\n"), gpg_strerror (rc));
    1611             :   else
    1612           0 :     okay = 1;
    1613           0 :   xfree (hexgrip);
    1614             : 
    1615             :  leave:
    1616           0 :   agent_release_card_info (&info);
    1617           0 :   return okay;
    1618             : }
    1619             : 
    1620             : 
    1621             : 
    1622             : /* Direct sending of an hex encoded APDU with error printing.  */
    1623             : static gpg_error_t
    1624           0 : send_apdu (const char *hexapdu, const char *desc, unsigned int ignore)
    1625             : {
    1626             :   gpg_error_t err;
    1627             :   unsigned int sw;
    1628             : 
    1629           0 :   err = agent_scd_apdu (hexapdu, &sw);
    1630           0 :   if (err)
    1631           0 :     tty_printf ("sending card command %s failed: %s\n", desc,
    1632             :                 gpg_strerror (err));
    1633           0 :   else if (!hexapdu || !strcmp (hexapdu, "undefined"))
    1634             :     ;
    1635           0 :   else if (ignore == 0xffff)
    1636             :     ; /* Ignore all status words.  */
    1637           0 :   else if (sw != 0x9000)
    1638             :     {
    1639           0 :       switch (sw)
    1640             :         {
    1641           0 :         case 0x6285: err = gpg_error (GPG_ERR_OBJ_TERM_STATE); break;
    1642           0 :         case 0x6982: err = gpg_error (GPG_ERR_BAD_PIN); break;
    1643           0 :         case 0x6985: err = gpg_error (GPG_ERR_USE_CONDITIONS); break;
    1644           0 :         default: err = gpg_error (GPG_ERR_CARD);
    1645             :         }
    1646           0 :       if (!(ignore && ignore == sw))
    1647           0 :         tty_printf ("card command %s failed: %s (0x%04x)\n", desc,
    1648             :                     gpg_strerror (err),  sw);
    1649             :     }
    1650           0 :   return err;
    1651             : }
    1652             : 
    1653             : 
    1654             : /* Do a factory reset after confirmation.  */
    1655             : static void
    1656           0 : factory_reset (void)
    1657             : {
    1658             :   struct agent_card_info_s info;
    1659             :   gpg_error_t err;
    1660           0 :   char *answer = NULL;
    1661           0 :   int termstate = 0;
    1662             :   int i;
    1663             : 
    1664             :   /*  The code below basically does the same what this
    1665             :       gpg-connect-agent script does:
    1666             : 
    1667             :         scd reset
    1668             :         scd serialno undefined
    1669             :         scd apdu 00 A4 04 00 06 D2 76 00 01 24 01
    1670             :         scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
    1671             :         scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
    1672             :         scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
    1673             :         scd apdu 00 20 00 81 08 40 40 40 40 40 40 40 40
    1674             :         scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
    1675             :         scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
    1676             :         scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
    1677             :         scd apdu 00 20 00 83 08 40 40 40 40 40 40 40 40
    1678             :         scd apdu 00 e6 00 00
    1679             :         scd reset
    1680             :         scd serialno undefined
    1681             :         scd apdu 00 A4 04 00 06 D2 76 00 01 24 01
    1682             :         scd apdu 00 44 00 00
    1683             :         /echo Card has been reset to factory defaults
    1684             : 
    1685             :       but tries to find out something about the card first.
    1686             :    */
    1687             : 
    1688           0 :   err = agent_scd_learn (&info, 0);
    1689           0 :   if (gpg_err_code (err) == GPG_ERR_OBJ_TERM_STATE
    1690           0 :       && gpg_err_source (err) == GPG_ERR_SOURCE_SCD)
    1691           0 :     termstate = 1;
    1692           0 :   else if (err)
    1693             :     {
    1694           0 :       log_error (_("OpenPGP card not available: %s\n"), gpg_strerror (err));
    1695           0 :       return;
    1696             :     }
    1697             : 
    1698           0 :   if (!termstate)
    1699             :     {
    1700           0 :       log_info (_("OpenPGP card no. %s detected\n"),
    1701           0 :                 info.serialno? info.serialno : "[none]");
    1702           0 :       if (!(info.status_indicator == 3 || info.status_indicator == 5))
    1703             :         {
    1704             :           /* Note: We won't see status-indicator 3 here because it is not
    1705             :              possible to select a card application in termination state.  */
    1706           0 :           log_error (_("This command is not supported by this card\n"));
    1707           0 :           goto leave;
    1708             :         }
    1709             : 
    1710           0 :       tty_printf ("\n");
    1711           0 :       log_info (_("Note: This command destroys all keys stored on the card!\n"));
    1712           0 :       tty_printf ("\n");
    1713           0 :       if (!cpr_get_answer_is_yes ("cardedit.factory-reset.proceed",
    1714           0 :                                   _("Continue? (y/N) ")))
    1715           0 :         goto leave;
    1716             : 
    1717             : 
    1718           0 :       answer = cpr_get ("cardedit.factory-reset.really",
    1719           0 :                         _("Really do a factory reset? (enter \"yes\") "));
    1720           0 :       cpr_kill_prompt ();
    1721           0 :       trim_spaces (answer);
    1722           0 :       if (strcmp (answer, "yes"))
    1723           0 :         goto leave;
    1724             : 
    1725             :       /* We need to select a card application before we can send APDUs
    1726             :          to the card without scdaemon doing anything on its own.  */
    1727           0 :       err = send_apdu (NULL, "RESET", 0);
    1728           0 :       if (err)
    1729           0 :         goto leave;
    1730           0 :       err = send_apdu ("undefined", "dummy select ", 0);
    1731           0 :       if (err)
    1732           0 :         goto leave;
    1733             : 
    1734             :       /* Select the OpenPGP application.  */
    1735           0 :       err = send_apdu ("00A4040006D27600012401", "SELECT AID", 0);
    1736           0 :       if (err)
    1737           0 :         goto leave;
    1738             : 
    1739             :       /* Do some dummy verifies with wrong PINs to set the retry
    1740             :          counter to zero.  We can't easily use the card version 2.1
    1741             :          feature of presenting the admin PIN to allow the terminate
    1742             :          command because there is no machinery in scdaemon to catch
    1743             :          the verify command and ask for the PIN when the "APDU"
    1744             :          command is used. */
    1745           0 :       for (i=0; i < 4; i++)
    1746           0 :         send_apdu ("00200081084040404040404040", "VERIFY", 0xffff);
    1747           0 :       for (i=0; i < 4; i++)
    1748           0 :         send_apdu ("00200083084040404040404040", "VERIFY", 0xffff);
    1749             : 
    1750             :       /* Send terminate datafile command.  */
    1751           0 :       err = send_apdu ("00e60000", "TERMINATE DF", 0x6985);
    1752           0 :       if (err)
    1753           0 :         goto leave;
    1754             :     }
    1755             : 
    1756             :   /* The card is in termination state - reset and select again.  */
    1757           0 :   err = send_apdu (NULL, "RESET", 0);
    1758           0 :   if (err)
    1759           0 :     goto leave;
    1760           0 :   err = send_apdu ("undefined", "dummy select", 0);
    1761           0 :   if (err)
    1762           0 :     goto leave;
    1763             : 
    1764             :   /* Select the OpenPGP application. (no error checking here). */
    1765           0 :   send_apdu ("00A4040006D27600012401", "SELECT AID", 0xffff);
    1766             : 
    1767             :   /* Send activate datafile command.  This is used without
    1768             :      confirmation if the card is already in termination state.  */
    1769           0 :   err = send_apdu ("00440000", "ACTIVATE DF", 0);
    1770           0 :   if (err)
    1771           0 :     goto leave;
    1772             : 
    1773             :   /* Finally we reset the card reader once more.  */
    1774           0 :   err = send_apdu (NULL, "RESET", 0);
    1775           0 :   if (err)
    1776           0 :     goto leave;
    1777             : 
    1778             :  leave:
    1779           0 :   xfree (answer);
    1780           0 :   agent_release_card_info (&info);
    1781             : }
    1782             : 
    1783             : 
    1784             : 
    1785             : /* Data used by the command parser.  This needs to be outside of the
    1786             :    function scope to allow readline based command completion.  */
    1787             : enum cmdids
    1788             :   {
    1789             :     cmdNOP = 0,
    1790             :     cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY,
    1791             :     cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR,
    1792             :     cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT,
    1793             :     cmdREADCERT, cmdUNBLOCK, cmdFACTORYRESET,
    1794             :     cmdINVCMD
    1795             :   };
    1796             : 
    1797             : static struct
    1798             : {
    1799             :   const char *name;
    1800             :   enum cmdids id;
    1801             :   int admin_only;
    1802             :   const char *desc;
    1803             : } cmds[] =
    1804             :   {
    1805             :     { "quit"    , cmdQUIT  , 0, N_("quit this menu")},
    1806             :     { "q"       , cmdQUIT  , 0, NULL },
    1807             :     { "admin"   , cmdADMIN , 0, N_("show admin commands")},
    1808             :     { "help"    , cmdHELP  , 0, N_("show this help")},
    1809             :     { "?"       , cmdHELP  , 0, NULL },
    1810             :     { "list"    , cmdLIST  , 0, N_("list all available data")},
    1811             :     { "l"       , cmdLIST  , 0, NULL },
    1812             :     { "debug"   , cmdDEBUG , 0, NULL },
    1813             :     { "name"    , cmdNAME  , 1, N_("change card holder's name")},
    1814             :     { "url"     , cmdURL   , 1, N_("change URL to retrieve key")},
    1815             :     { "fetch"   , cmdFETCH , 0, N_("fetch the key specified in the card URL")},
    1816             :     { "login"   , cmdLOGIN , 1, N_("change the login name")},
    1817             :     { "lang"    , cmdLANG  , 1, N_("change the language preferences")},
    1818             :     { "sex"     , cmdSEX   , 1, N_("change card holder's sex")},
    1819             :     { "cafpr"   , cmdCAFPR , 1, N_("change a CA fingerprint")},
    1820             :     { "forcesig", cmdFORCESIG, 1, N_("toggle the signature force PIN flag")},
    1821             :     { "generate", cmdGENERATE, 1, N_("generate new keys")},
    1822             :     { "passwd"  , cmdPASSWD, 0, N_("menu to change or unblock the PIN")},
    1823             :     { "verify"  , cmdVERIFY, 0, N_("verify the PIN and list all data")},
    1824             :     { "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") },
    1825             :     { "factory-reset", cmdFACTORYRESET, 1, N_("destroy all keys and data")},
    1826             :     /* Note, that we do not announce these command yet. */
    1827             :     { "privatedo", cmdPRIVATEDO, 0, NULL },
    1828             :     { "readcert", cmdREADCERT, 0, NULL },
    1829             :     { "writecert", cmdWRITECERT, 1, NULL },
    1830             :     { NULL, cmdINVCMD, 0, NULL }
    1831             :   };
    1832             : 
    1833             : 
    1834             : #ifdef HAVE_LIBREADLINE
    1835             : 
    1836             : /* These two functions are used by readline for command completion. */
    1837             : 
    1838             : static char *
    1839             : command_generator(const char *text,int state)
    1840             : {
    1841             :   static int list_index,len;
    1842             :   const char *name;
    1843             : 
    1844             :   /* If this is a new word to complete, initialize now.  This includes
    1845             :      saving the length of TEXT for efficiency, and initializing the
    1846             :      index variable to 0. */
    1847             :   if(!state)
    1848             :     {
    1849             :       list_index=0;
    1850             :       len=strlen(text);
    1851             :     }
    1852             : 
    1853             :   /* Return the next partial match */
    1854             :   while((name=cmds[list_index].name))
    1855             :     {
    1856             :       /* Only complete commands that have help text */
    1857             :       if(cmds[list_index++].desc && strncmp(name,text,len)==0)
    1858             :         return strdup(name);
    1859             :     }
    1860             : 
    1861             :   return NULL;
    1862             : }
    1863             : 
    1864             : static char **
    1865             : card_edit_completion(const char *text, int start, int end)
    1866             : {
    1867             :   (void)end;
    1868             :   /* If we are at the start of a line, we try and command-complete.
    1869             :      If not, just do nothing for now. */
    1870             : 
    1871             :   if(start==0)
    1872             :     return rl_completion_matches(text,command_generator);
    1873             : 
    1874             :   rl_attempted_completion_over=1;
    1875             : 
    1876             :   return NULL;
    1877             : }
    1878             : #endif /*HAVE_LIBREADLINE*/
    1879             : 
    1880             : /* Menu to edit all user changeable values on an OpenPGP card.  Only
    1881             :    Key creation is not handled here. */
    1882             : void
    1883           0 : card_edit (ctrl_t ctrl, strlist_t commands)
    1884             : {
    1885           0 :   enum cmdids cmd = cmdNOP;
    1886           0 :   int have_commands = !!commands;
    1887           0 :   int redisplay = 1;
    1888           0 :   char *answer = NULL;
    1889           0 :   int allow_admin=0;
    1890             :   char serialnobuf[50];
    1891             : 
    1892             : 
    1893           0 :   if (opt.command_fd != -1)
    1894             :     ;
    1895           0 :   else if (opt.batch && !have_commands)
    1896             :     {
    1897           0 :       log_error(_("can't do this in batch mode\n"));
    1898           0 :       goto leave;
    1899             :     }
    1900             : 
    1901             :   for (;;)
    1902             :     {
    1903             :       int arg_number;
    1904           0 :       const char *arg_string = "";
    1905           0 :       const char *arg_rest = "";
    1906             :       char *p;
    1907             :       int i;
    1908             :       int cmd_admin_only;
    1909             : 
    1910           0 :       tty_printf("\n");
    1911           0 :       if (redisplay )
    1912             :         {
    1913           0 :           if (opt.with_colons)
    1914             :             {
    1915           0 :               card_status (es_stdout, serialnobuf, DIM (serialnobuf));
    1916           0 :               fflush (stdout);
    1917             :             }
    1918             :           else
    1919             :             {
    1920           0 :               card_status (NULL, serialnobuf, DIM (serialnobuf));
    1921           0 :               tty_printf("\n");
    1922             :             }
    1923           0 :           redisplay = 0;
    1924             :         }
    1925             : 
    1926             :       do
    1927             :         {
    1928           0 :           xfree (answer);
    1929           0 :           if (have_commands)
    1930             :             {
    1931           0 :               if (commands)
    1932             :                 {
    1933           0 :                   answer = xstrdup (commands->d);
    1934           0 :                   commands = commands->next;
    1935             :                 }
    1936           0 :               else if (opt.batch)
    1937             :                 {
    1938           0 :                   answer = xstrdup ("quit");
    1939             :                 }
    1940             :               else
    1941           0 :                 have_commands = 0;
    1942             :             }
    1943             : 
    1944           0 :             if (!have_commands)
    1945             :               {
    1946             :                 tty_enable_completion (card_edit_completion);
    1947           0 :                 answer = cpr_get_no_help("cardedit.prompt", _("gpg/card> "));
    1948           0 :                 cpr_kill_prompt();
    1949             :                 tty_disable_completion ();
    1950             :               }
    1951           0 :             trim_spaces(answer);
    1952             :         }
    1953           0 :       while ( *answer == '#' );
    1954             : 
    1955           0 :       arg_number = 0; /* Yes, here is the init which egcc complains about */
    1956           0 :       cmd_admin_only = 0;
    1957           0 :       if (!*answer)
    1958           0 :         cmd = cmdLIST; /* Default to the list command */
    1959           0 :       else if (*answer == CONTROL_D)
    1960           0 :         cmd = cmdQUIT;
    1961             :       else
    1962             :         {
    1963           0 :           if ((p=strchr (answer,' ')))
    1964             :             {
    1965           0 :               *p++ = 0;
    1966           0 :               trim_spaces (answer);
    1967           0 :               trim_spaces (p);
    1968           0 :               arg_number = atoi(p);
    1969           0 :               arg_string = p;
    1970           0 :               arg_rest = p;
    1971           0 :               while (digitp (arg_rest))
    1972           0 :                 arg_rest++;
    1973           0 :               while (spacep (arg_rest))
    1974           0 :                 arg_rest++;
    1975             :             }
    1976             : 
    1977           0 :           for (i=0; cmds[i].name; i++ )
    1978           0 :             if (!ascii_strcasecmp (answer, cmds[i].name ))
    1979           0 :               break;
    1980             : 
    1981           0 :           cmd = cmds[i].id;
    1982           0 :           cmd_admin_only = cmds[i].admin_only;
    1983             :         }
    1984             : 
    1985           0 :       if (!allow_admin && cmd_admin_only)
    1986             :         {
    1987           0 :           tty_printf ("\n");
    1988           0 :           tty_printf (_("Admin-only command\n"));
    1989           0 :           continue;
    1990             :         }
    1991             : 
    1992           0 :       switch (cmd)
    1993             :         {
    1994             :         case cmdHELP:
    1995           0 :           for (i=0; cmds[i].name; i++ )
    1996           0 :             if(cmds[i].desc
    1997           0 :                && (!cmds[i].admin_only || (cmds[i].admin_only && allow_admin)))
    1998           0 :               tty_printf("%-14s %s\n", cmds[i].name, _(cmds[i].desc) );
    1999           0 :           break;
    2000             : 
    2001             :         case cmdADMIN:
    2002           0 :           if ( !strcmp (arg_string, "on") )
    2003           0 :             allow_admin = 1;
    2004           0 :           else if ( !strcmp (arg_string, "off") )
    2005           0 :             allow_admin = 0;
    2006           0 :           else if ( !strcmp (arg_string, "verify") )
    2007             :             {
    2008             :               /* Force verification of the Admin Command.  However,
    2009             :                  this is only done if the retry counter is at initial
    2010             :                  state.  */
    2011           0 :               char *tmp = xmalloc (strlen (serialnobuf) + 6 + 1);
    2012           0 :               strcpy (stpcpy (tmp, serialnobuf), "[CHV3]");
    2013           0 :               allow_admin = !agent_scd_checkpin (tmp);
    2014           0 :               xfree (tmp);
    2015             :             }
    2016             :           else /* Toggle. */
    2017           0 :             allow_admin=!allow_admin;
    2018           0 :           if(allow_admin)
    2019           0 :             tty_printf(_("Admin commands are allowed\n"));
    2020             :           else
    2021           0 :             tty_printf(_("Admin commands are not allowed\n"));
    2022           0 :           break;
    2023             : 
    2024             :         case cmdVERIFY:
    2025           0 :           agent_scd_checkpin (serialnobuf);
    2026           0 :           redisplay = 1;
    2027           0 :           break;
    2028             : 
    2029             :         case cmdLIST:
    2030           0 :           redisplay = 1;
    2031           0 :           break;
    2032             : 
    2033             :         case cmdNAME:
    2034           0 :           change_name ();
    2035           0 :           break;
    2036             : 
    2037             :         case cmdURL:
    2038           0 :           change_url ();
    2039           0 :           break;
    2040             : 
    2041             :         case cmdFETCH:
    2042           0 :           fetch_url (ctrl);
    2043           0 :           break;
    2044             : 
    2045             :         case cmdLOGIN:
    2046           0 :           change_login (arg_string);
    2047           0 :           break;
    2048             : 
    2049             :         case cmdLANG:
    2050           0 :           change_lang ();
    2051           0 :           break;
    2052             : 
    2053             :         case cmdSEX:
    2054           0 :           change_sex ();
    2055           0 :           break;
    2056             : 
    2057             :         case cmdCAFPR:
    2058           0 :           if ( arg_number < 1 || arg_number > 3 )
    2059           0 :             tty_printf ("usage: cafpr N\n"
    2060             :                         "       1 <= N <= 3\n");
    2061             :           else
    2062           0 :             change_cafpr (arg_number);
    2063           0 :           break;
    2064             : 
    2065             :         case cmdPRIVATEDO:
    2066           0 :           if ( arg_number < 1 || arg_number > 4 )
    2067           0 :             tty_printf ("usage: privatedo N\n"
    2068             :                         "       1 <= N <= 4\n");
    2069             :           else
    2070           0 :             change_private_do (arg_string, arg_number);
    2071           0 :           break;
    2072             : 
    2073             :         case cmdWRITECERT:
    2074           0 :           if ( arg_number != 3 )
    2075           0 :             tty_printf ("usage: writecert 3 < FILE\n");
    2076             :           else
    2077           0 :             change_cert (arg_rest);
    2078           0 :           break;
    2079             : 
    2080             :         case cmdREADCERT:
    2081           0 :           if ( arg_number != 3 )
    2082           0 :             tty_printf ("usage: readcert 3 > FILE\n");
    2083             :           else
    2084           0 :             read_cert (arg_rest);
    2085           0 :           break;
    2086             : 
    2087             :         case cmdFORCESIG:
    2088           0 :           toggle_forcesig ();
    2089           0 :           break;
    2090             : 
    2091             :         case cmdGENERATE:
    2092           0 :           generate_card_keys (ctrl);
    2093           0 :           break;
    2094             : 
    2095             :         case cmdPASSWD:
    2096           0 :           change_pin (0, allow_admin);
    2097           0 :           break;
    2098             : 
    2099             :         case cmdUNBLOCK:
    2100           0 :           change_pin (1, allow_admin);
    2101           0 :           break;
    2102             : 
    2103             :         case cmdFACTORYRESET:
    2104           0 :           factory_reset ();
    2105           0 :           break;
    2106             : 
    2107             :         case cmdQUIT:
    2108           0 :           goto leave;
    2109             : 
    2110             :         case cmdNOP:
    2111           0 :           break;
    2112             : 
    2113             :         case cmdINVCMD:
    2114             :         default:
    2115           0 :           tty_printf ("\n");
    2116           0 :           tty_printf (_("Invalid command  (try \"help\")\n"));
    2117           0 :           break;
    2118             :         } /* End command switch. */
    2119           0 :     } /* End of main menu loop. */
    2120             : 
    2121             :  leave:
    2122           0 :   xfree (answer);
    2123           0 : }

Generated by: LCOV version 1.11