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

Generated by: LCOV version 1.11