agent: Stop scdaemon after reload when disable_scdaemon.
[gnupg.git] / tools / card-call-scd.c
1 /* card-call-scd.c - IPC calls to scdaemon.
2  * Copyright (C) 2019 g10 Code GmbH
3  * Copyright (C) 2001-2003, 2006-2011, 2013 Free Software Foundation, Inc.
4  * Copyright (C) 2013-2015  Werner Koch
5  *
6  * This file is part of GnuPG.
7  *
8  * GnuPG is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * GnuPG is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, see <https://www.gnu.org/licenses/>.
20  * SPDX-License-Identifier: GPL-3.0-or-later
21  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <unistd.h>
29 #include <time.h>
30 #ifdef HAVE_LOCALE_H
31 #include <locale.h>
32 #endif
33
34 #include "../common/util.h"
35 #include "../common/membuf.h"
36 #include "../common/i18n.h"
37 #include "../common/asshelp.h"
38 #include "../common/sysutils.h"
39 #include "../common/status.h"
40 #include "../common/host2net.h"
41 #include "../common/openpgpdefs.h"
42 #include "gpg-card.h"
43
44 #define CONTROL_D ('D' - 'A' + 1)
45
46 #define START_AGENT_NO_STARTUP_CMDS 1
47 #define START_AGENT_SUPPRESS_ERRORS 2
48
49 struct default_inq_parm_s
50 {
51   assuan_context_t ctx;
52   struct {
53     u32 *keyid;
54     u32 *mainkeyid;
55     int pubkey_algo;
56   } keyinfo;
57 };
58
59 struct cipher_parm_s
60 {
61   struct default_inq_parm_s *dflt;
62   assuan_context_t ctx;
63   unsigned char *ciphertext;
64   size_t ciphertextlen;
65 };
66
67 struct writecert_parm_s
68 {
69   struct default_inq_parm_s *dflt;
70   const unsigned char *certdata;
71   size_t certdatalen;
72 };
73
74 struct writekey_parm_s
75 {
76   struct default_inq_parm_s *dflt;
77   const unsigned char *keydata;
78   size_t keydatalen;
79 };
80
81 struct genkey_parm_s
82 {
83   struct default_inq_parm_s *dflt;
84   const char *keyparms;
85   const char *passphrase;
86 };
87
88 struct card_cardlist_parm_s
89 {
90   gpg_error_t error;
91   strlist_t list;
92 };
93
94 struct import_key_parm_s
95 {
96   struct default_inq_parm_s *dflt;
97   const void *key;
98   size_t keylen;
99 };
100
101
102 struct cache_nonce_parm_s
103 {
104   char **cache_nonce_addr;
105   char **passwd_nonce_addr;
106 };
107
108
109 \f
110 /*
111  * File local variables
112  */
113
114 /* The established context to the agent.  Note that all calls to
115  * scdaemon are routed via the agent and thus we only need to care
116  * about the IPC with the agent.  */
117 static assuan_context_t agent_ctx;
118
119
120 \f
121 /*
122  * Local prototypes
123  */
124 static gpg_error_t learn_status_cb (void *opaque, const char *line);
125
126
127
128 \f
129 /* Release the card info structure INFO. */
130 void
131 release_card_info (card_info_t info)
132 {
133   int i;
134
135
136   if (!info)
137     return;
138
139   xfree (info->reader); info->reader = NULL;
140   xfree (info->cardtype); info->cardtype = NULL;
141   xfree (info->serialno); info->serialno = NULL;
142   xfree (info->dispserialno); info->dispserialno = NULL;
143   xfree (info->apptypestr); info->apptypestr = NULL;
144   info->apptype = APP_TYPE_NONE;
145   xfree (info->disp_name); info->disp_name = NULL;
146   xfree (info->disp_lang); info->disp_lang = NULL;
147   xfree (info->pubkey_url); info->pubkey_url = NULL;
148   xfree (info->login_data); info->login_data = NULL;
149   info->cafpr1len = info->cafpr2len = info->cafpr3len = 0;
150   for (i=0; i < DIM(info->private_do); i++)
151     {
152       xfree (info->private_do[i]);
153       info->private_do[i] = NULL;
154     }
155   while (info->kinfo)
156     {
157       key_info_t kinfo = info->kinfo->next;
158       xfree (info->kinfo);
159       info->kinfo = kinfo;
160     }
161   info->chvusage[0] = info->chvusage[1] = 0;
162 }
163
164
165 /* Map an application type string to an integer.  */
166 static app_type_t
167 map_apptypestr (const char *string)
168 {
169   app_type_t result;
170
171   if (!string)
172     result = APP_TYPE_NONE;
173   else if (!ascii_strcasecmp (string, "OPENPGP"))
174     result = APP_TYPE_OPENPGP;
175   else if (!ascii_strcasecmp (string, "NKS"))
176     result = APP_TYPE_NKS;
177   else if (!ascii_strcasecmp (string, "DINSIG"))
178     result = APP_TYPE_DINSIG;
179   else if (!ascii_strcasecmp (string, "P15"))
180     result = APP_TYPE_P15;
181   else if (!ascii_strcasecmp (string, "GELDKARTE"))
182     result = APP_TYPE_GELDKARTE;
183   else if (!ascii_strcasecmp (string, "SC-HSM"))
184     result = APP_TYPE_SC_HSM;
185   else if (!ascii_strcasecmp (string, "PIV"))
186     result = APP_TYPE_PIV;
187   else
188     result = APP_TYPE_UNKNOWN;
189
190   return result;
191 }
192
193
194 /* Return a string representation of the application type.  */
195 const char *
196 app_type_string (app_type_t app_type)
197 {
198   const char *result = "?";
199   switch (app_type)
200     {
201     case APP_TYPE_NONE:      result = "None"; break;
202     case APP_TYPE_OPENPGP:   result = "OpenPGP"; break;
203     case APP_TYPE_NKS:       result = "NetKey"; break;
204     case APP_TYPE_DINSIG:    result = "DINSIG"; break;
205     case APP_TYPE_P15:       result = "P15"; break;
206     case APP_TYPE_GELDKARTE: result = "Geldkarte"; break;
207     case APP_TYPE_SC_HSM:    result = "SC-HSM"; break;
208     case APP_TYPE_PIV:       result = "PIV"; break;
209     case APP_TYPE_UNKNOWN:   result = "Unknown"; break;
210     }
211   return result;
212 }
213
214
215
216 /* If RC is not 0, write an appropriate status message. */
217 static gpg_error_t
218 status_sc_op_failure (gpg_error_t err)
219 {
220   switch (gpg_err_code (err))
221     {
222     case 0:
223       break;
224     case GPG_ERR_CANCELED:
225     case GPG_ERR_FULLY_CANCELED:
226       gnupg_status_printf (STATUS_SC_OP_FAILURE, "1");
227       break;
228     case GPG_ERR_BAD_PIN:
229       gnupg_status_printf (STATUS_SC_OP_FAILURE, "2");
230       break;
231     default:
232       gnupg_status_printf (STATUS_SC_OP_FAILURE, NULL);
233       break;
234     }
235   return err;
236 }
237
238
239 /* This is the default inquiry callback.  It mainly handles the
240    Pinentry notifications.  */
241 static gpg_error_t
242 default_inq_cb (void *opaque, const char *line)
243 {
244   gpg_error_t err = 0;
245   struct default_inq_parm_s *parm = opaque;
246
247   (void)parm;
248
249   if (has_leading_keyword (line, "PINENTRY_LAUNCHED"))
250     {
251       /* err = gpg_proxy_pinentry_notify (parm->ctrl, line); */
252       /* if (err) */
253       /*   log_error (_("failed to proxy %s inquiry to client\n"), */
254       /*              "PINENTRY_LAUNCHED"); */
255       /* We do not pass errors to avoid breaking other code.  */
256     }
257   else
258     log_debug ("ignoring gpg-agent inquiry '%s'\n", line);
259
260   return err;
261 }
262
263
264 /* Print a warning if the server's version number is less than our
265    version number.  Returns an error code on a connection problem.  */
266 static gpg_error_t
267 warn_version_mismatch (assuan_context_t ctx, const char *servername, int mode)
268 {
269   gpg_error_t err;
270   char *serverversion;
271   const char *myversion = strusage (13);
272
273   err = get_assuan_server_version (ctx, mode, &serverversion);
274   if (err)
275     log_log (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED?
276              GPGRT_LOGLVL_INFO : GPGRT_LOGLVL_ERROR,
277              _("error getting version from '%s': %s\n"),
278              servername, gpg_strerror (err));
279   else if (compare_version_strings (serverversion, myversion) < 0)
280     {
281       char *warn;
282
283       warn = xtryasprintf (_("server '%s' is older than us (%s < %s)"),
284                            servername, serverversion, myversion);
285       if (!warn)
286         err = gpg_error_from_syserror ();
287       else
288         {
289           log_info (_("WARNING: %s\n"), warn);
290           if (!opt.quiet)
291             {
292               log_info (_("Note: Outdated servers may lack important"
293                           " security fixes.\n"));
294               log_info (_("Note: Use the command \"%s\" to restart them.\n"),
295                         "gpgconf --kill all");
296             }
297           gnupg_status_printf (STATUS_WARNING, "server_version_mismatch 0 %s",
298                                warn);
299           xfree (warn);
300         }
301     }
302   xfree (serverversion);
303   return err;
304 }
305
306
307 /* Try to connect to the agent via socket or fork it off and work by
308  * pipes.  Handle the server's initial greeting.  */
309 static gpg_error_t
310 start_agent (unsigned int flags)
311 {
312   gpg_error_t err;
313   int started = 0;
314
315   if (agent_ctx)
316     err = 0;
317   else
318     {
319       started = 1;
320       err = start_new_gpg_agent (&agent_ctx,
321                                  GPG_ERR_SOURCE_DEFAULT,
322                                  opt.agent_program,
323                                  opt.lc_ctype, opt.lc_messages,
324                                  opt.session_env,
325                                  opt.autostart, opt.verbose, DBG_IPC,
326                                  NULL, NULL);
327       if (!opt.autostart && gpg_err_code (err) == GPG_ERR_NO_AGENT)
328         {
329           static int shown;
330
331           if (!shown)
332             {
333               shown = 1;
334               log_info (_("no gpg-agent running in this session\n"));
335             }
336         }
337       else if (!err
338                && !(err = warn_version_mismatch (agent_ctx, GPG_AGENT_NAME, 0)))
339         {
340           /* Tell the agent that we support Pinentry notifications.
341              No error checking so that it will work also with older
342              agents.  */
343           assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
344                            NULL, NULL, NULL, NULL, NULL, NULL);
345           /* Tell the agent about what version we are aware.  This is
346              here used to indirectly enable GPG_ERR_FULLY_CANCELED.  */
347           assuan_transact (agent_ctx, "OPTION agent-awareness=2.1.0",
348                            NULL, NULL, NULL, NULL, NULL, NULL);
349         }
350     }
351
352   if (started && !err && !(flags & START_AGENT_NO_STARTUP_CMDS))
353     {
354       /* Request the serial number of the card for an early test.  */
355       struct card_info_s info;
356
357       memset (&info, 0, sizeof info);
358
359       if (!(flags & START_AGENT_SUPPRESS_ERRORS))
360         err = warn_version_mismatch (agent_ctx, SCDAEMON_NAME, 2);
361
362       if (!err)
363         err = assuan_transact (agent_ctx, "SCD SERIALNO",
364                                NULL, NULL, NULL, NULL,
365                                learn_status_cb, &info);
366       if (err && !(flags & START_AGENT_SUPPRESS_ERRORS))
367         {
368           switch (gpg_err_code (err))
369             {
370             case GPG_ERR_NOT_SUPPORTED:
371             case GPG_ERR_NO_SCDAEMON:
372               gnupg_status_printf (STATUS_CARDCTRL, "6"); /* No card support. */
373               break;
374             case GPG_ERR_OBJ_TERM_STATE:
375               /* Card is in termination state. */
376               gnupg_status_printf (STATUS_CARDCTRL, "7");
377               break;
378             default:
379               gnupg_status_printf (STATUS_CARDCTRL, "4");  /* No card.  */
380               break;
381             }
382         }
383
384       if (!err && info.serialno)
385         gnupg_status_printf (STATUS_CARDCTRL, "3 %s", info.serialno);
386
387       release_card_info (&info);
388     }
389
390   return err;
391 }
392
393
394 /* Return a new malloced string by unescaping the string S.  Escaping
395  * is percent escaping and '+'/space mapping.  A binary nul will
396  * silently be replaced by a 0xFF.  Function returns NULL to indicate
397  * an out of memory status. */
398 static char *
399 unescape_status_string (const unsigned char *s)
400 {
401   return percent_plus_unescape (s, 0xff);
402 }
403
404
405 /* Take a 20 or 32 byte hexencoded string and put it into the provided
406  * FPRLEN byte long buffer FPR in binary format.  Returns the actual
407  * used length of the FPR buffer or 0 on error.  */
408 static unsigned int
409 unhexify_fpr (const char *hexstr, unsigned char *fpr, unsigned int fprlen)
410 {
411   const char *s;
412   int n;
413
414   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
415     ;
416   if ((*s && *s != ' ') || !(n == 40 || n == 64))
417     return 0; /* no fingerprint (invalid or wrong length). */
418   for (s=hexstr, n=0; *s && n < fprlen; s += 2, n++)
419     fpr[n] = xtoi_2 (s);
420
421   return (n == 20 || n == 32)? n : 0;
422 }
423
424
425 /* Take the serial number from LINE and return it verbatim in a newly
426  * allocated string.  We make sure that only hex characters are
427  * returned.  Returns NULL on error. */
428 static char *
429 store_serialno (const char *line)
430 {
431   const char *s;
432   char *p;
433
434   for (s=line; hexdigitp (s); s++)
435     ;
436   p = xtrymalloc (s + 1 - line);
437   if (p)
438     {
439       memcpy (p, line, s-line);
440       p[s-line] = 0;
441     }
442   return p;
443 }
444
445
446 \f
447 /* Send an APDU to the current card.  On success the status word is
448  * stored at R_SW inless R_SW is NULL.  With HEXAPDU being NULL only a
449  * RESET command is send to scd.  With HEXAPDU being the string
450  * "undefined" the command "SERIALNO undefined" is send to scd.  If
451  * R_DATA is not NULL the data is without the status code is stored
452  * there.  Caller must release it.  */
453 gpg_error_t
454 scd_apdu (const char *hexapdu, unsigned int *r_sw,
455           unsigned char **r_data, size_t *r_datalen)
456 {
457   gpg_error_t err;
458
459   if (r_data)
460     *r_data = NULL;
461   if (r_datalen)
462     *r_datalen = 0;
463
464   err = start_agent (START_AGENT_NO_STARTUP_CMDS);
465   if (err)
466     return err;
467
468   if (!hexapdu)
469     {
470       err = assuan_transact (agent_ctx, "SCD RESET",
471                              NULL, NULL, NULL, NULL, NULL, NULL);
472
473     }
474   else if (!strcmp (hexapdu, "undefined"))
475     {
476       err = assuan_transact (agent_ctx, "SCD SERIALNO undefined",
477                              NULL, NULL, NULL, NULL, NULL, NULL);
478     }
479   else
480     {
481       char line[ASSUAN_LINELENGTH];
482       membuf_t mb;
483       unsigned char *data;
484       size_t datalen;
485
486       init_membuf (&mb, 256);
487
488       snprintf (line, DIM(line), "SCD APDU %s", hexapdu);
489       err = assuan_transact (agent_ctx, line,
490                              put_membuf_cb, &mb, NULL, NULL, NULL, NULL);
491       if (!err)
492         {
493           data = get_membuf (&mb, &datalen);
494           if (!data)
495             err = gpg_error_from_syserror ();
496           else if (datalen < 2) /* Ooops */
497             err = gpg_error (GPG_ERR_CARD);
498           else
499             {
500               if (r_sw)
501                 *r_sw = buf16_to_uint (data+datalen-2);
502               if (r_data && r_datalen)
503                 {
504                   *r_data = data;
505                   *r_datalen = datalen - 2;
506                   data = NULL;
507                 }
508             }
509           xfree (data);
510         }
511     }
512
513   return err;
514 }
515
516
517 /* This is a dummy data line callback.  */
518 static gpg_error_t
519 dummy_data_cb (void *opaque, const void *buffer, size_t length)
520 {
521   (void)opaque;
522   (void)buffer;
523   (void)length;
524   return 0;
525 }
526
527 /* A simple callback used to return the serialnumber of a card.  */
528 static gpg_error_t
529 get_serialno_cb (void *opaque, const char *line)
530 {
531   char **serialno = opaque;
532   const char *keyword = line;
533   const char *s;
534   int keywordlen, n;
535
536   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
537     ;
538   while (spacep (line))
539     line++;
540
541   /* FIXME: Should we use has_leading_keyword? */
542   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
543     {
544       if (*serialno)
545         return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
546       for (n=0,s=line; hexdigitp (s); s++, n++)
547         ;
548       if (!n || (n&1)|| !(spacep (s) || !*s) )
549         return gpg_error (GPG_ERR_ASS_PARAMETER);
550       *serialno = xtrymalloc (n+1);
551       if (!*serialno)
552         return out_of_core ();
553       memcpy (*serialno, line, n);
554       (*serialno)[n] = 0;
555     }
556
557   return 0;
558 }
559
560
561
562 /* For historical reasons OpenPGP cards simply use the numbers 1 to 3
563  * for the <keyref>.  Other cards and future versions of
564  * scd/app-openpgp.c may print the full keyref; i.e. "OpenPGP.1"
565  * instead of "1".  This is a helper to cope with that. */
566 static const char *
567 parse_keyref_helper (const char *string)
568 {
569   if (*string == '1' && spacep (string+1))
570     return "OPENPGP.1";
571   else if (*string == '2' && spacep (string+1))
572     return "OPENPGP.2";
573   else if (*string == '3' && spacep (string+1))
574     return "OPENPGP.3";
575   else
576     return string;
577 }
578
579
580 /* Create a new key info object with KEYREF.  All fields but the
581  * keyref are zeroed out.  Never returns NULL.  The created object is
582  * appended to the list at INFO. */
583 static key_info_t
584 create_kinfo (card_info_t info, const char *keyref)
585 {
586   key_info_t kinfo, ki;
587
588   kinfo = xcalloc (1, sizeof *kinfo + strlen (keyref));
589   strcpy (kinfo->keyref, keyref);
590
591   if (!info->kinfo)
592     info->kinfo = kinfo;
593   else
594     {
595       for (ki=info->kinfo; ki->next; ki = ki->next)
596         ;
597       ki->next = kinfo;
598     }
599   return kinfo;
600 }
601
602
603 /* The status callback to handle the LEARN and GETATTR commands.  */
604 static gpg_error_t
605 learn_status_cb (void *opaque, const char *line)
606 {
607   struct card_info_s *parm = opaque;
608   const char *keyword = line;
609   int keywordlen;
610   char *line_buffer = NULL; /* In case we need a copy.  */
611   char *pline;
612   key_info_t kinfo;
613   const char *keyref;
614   int i;
615
616   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
617     ;
618   while (spacep (line))
619     line++;
620
621   switch (keywordlen)
622     {
623     case 3:
624       if (!memcmp (keyword, "KDF", 3))
625         {
626           parm->kdf_do_enabled = 1;
627         }
628       break;
629
630     case 5:
631       if (!memcmp (keyword, "UIF-", 4)
632           && strchr("123", keyword[4]))
633         {
634           unsigned char *data;
635           int no = keyword[4] - '1';
636
637           log_assert (no >= 0 && no <= 2);
638           data = unescape_status_string (line);
639           parm->uif[no] = (data[0] != 0xff);
640           xfree (data);
641         }
642       break;
643
644     case 6:
645       if (!memcmp (keyword, "READER", keywordlen))
646         {
647           xfree (parm->reader);
648           parm->reader = unescape_status_string (line);
649         }
650       else if (!memcmp (keyword, "EXTCAP", keywordlen))
651         {
652           char *p, *p2, *buf;
653           int abool;
654
655           buf = p = unescape_status_string (line);
656           if (buf)
657             {
658               for (p = strtok (buf, " "); p; p = strtok (NULL, " "))
659                 {
660                   p2 = strchr (p, '=');
661                   if (p2)
662                     {
663                       *p2++ = 0;
664                       abool = (*p2 == '1');
665                       if (!strcmp (p, "ki"))
666                         parm->extcap.ki = abool;
667                       else if (!strcmp (p, "aac"))
668                         parm->extcap.aac = abool;
669                       else if (!strcmp (p, "bt"))
670                         parm->extcap.bt = abool;
671                       else if (!strcmp (p, "kdf"))
672                         parm->extcap.kdf = abool;
673                       else if (!strcmp (p, "si"))
674                         parm->status_indicator = strtoul (p2, NULL, 10);
675                     }
676                 }
677               xfree (buf);
678             }
679         }
680       else if (!memcmp (keyword, "CA-FPR", keywordlen))
681         {
682           int no = atoi (line);
683           while (*line && !spacep (line))
684             line++;
685           while (spacep (line))
686             line++;
687           if (no == 1)
688             parm->cafpr1len = unhexify_fpr (line, parm->cafpr1,
689                                             sizeof parm->cafpr1);
690           else if (no == 2)
691             parm->cafpr2len = unhexify_fpr (line, parm->cafpr2,
692                                             sizeof parm->cafpr2);
693           else if (no == 3)
694             parm->cafpr3len = unhexify_fpr (line, parm->cafpr3,
695                                             sizeof parm->cafpr3);
696         }
697       break;
698
699     case 7:
700       if (!memcmp (keyword, "APPTYPE", keywordlen))
701         {
702           xfree (parm->apptypestr);
703           parm->apptypestr = unescape_status_string (line);
704           parm->apptype = map_apptypestr (parm->apptypestr);
705         }
706       else if (!memcmp (keyword, "KEY-FPR", keywordlen))
707         {
708           /* The format of such a line is:
709            *   KEY-FPR <keyref> <fingerprintinhex>
710            */
711           const char *fpr;
712
713           line_buffer = pline = xstrdup (line);
714
715           keyref = parse_keyref_helper (pline);
716           while (*pline && !spacep (pline))
717             pline++;
718           if (*pline)
719             *pline++ = 0; /* Terminate keyref.  */
720           while (spacep (pline)) /* Skip to the fingerprint.  */
721             pline++;
722           fpr = pline;
723
724           /* Check whether we already have an item for the keyref.  */
725           kinfo = find_kinfo (parm, keyref);
726           if (!kinfo)  /* No: new entry.  */
727             kinfo = create_kinfo (parm, keyref);
728           else /* Existing entry - clear the fpr.  */
729             memset (kinfo->fpr, 0, sizeof kinfo->fpr);
730
731           /* Set or update or the fingerprint.  */
732           kinfo->fprlen = unhexify_fpr (fpr, kinfo->fpr, sizeof kinfo->fpr);
733         }
734       break;
735
736     case 8:
737       if (!memcmp (keyword, "SERIALNO", keywordlen))
738         {
739           xfree (parm->serialno);
740           parm->serialno = store_serialno (line);
741           parm->is_v2 = (strlen (parm->serialno) >= 16
742                          && xtoi_2 (parm->serialno+12) >= 2 );
743         }
744       else if (!memcmp (keyword, "CARDTYPE", keywordlen))
745         {
746           xfree (parm->cardtype);
747           parm->cardtype = unescape_status_string (line);
748         }
749       else if (!memcmp (keyword, "DISP-SEX", keywordlen))
750         {
751           parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
752         }
753       else if (!memcmp (keyword, "KEY-TIME", keywordlen))
754         {
755           /* The format of such a line is:
756            *   KEY-TIME <keyref> <timestamp>
757            */
758           const char *timestamp;
759
760           line_buffer = pline = xstrdup (line);
761
762           keyref = parse_keyref_helper (pline);
763           while (*pline && !spacep (pline))
764             pline++;
765           if (*pline)
766             *pline++ = 0; /* Terminate keyref.  */
767           while (spacep (pline)) /* Skip to the timestamp.  */
768             pline++;
769           timestamp = pline;
770
771           /* Check whether we already have an item for the keyref.  */
772           kinfo = find_kinfo (parm, keyref);
773           if (!kinfo)  /* No: new entry.  */
774             kinfo = create_kinfo (parm, keyref);
775
776           kinfo->created = strtoul (timestamp, NULL, 10);
777         }
778       else if (!memcmp (keyword, "KEY-ATTR", keywordlen))
779         {
780           int keyno = 0;
781           int algo = GCRY_PK_RSA;
782           int n = 0;
783
784           sscanf (line, "%d %d %n", &keyno, &algo, &n);
785           keyno--;
786           if (keyno < 0 || keyno >= DIM (parm->key_attr))
787             ; /* Out of range - ignore.  */
788           else
789             {
790               parm->key_attr[keyno].algo = algo;
791               if (algo == PUBKEY_ALGO_RSA)
792                 parm->key_attr[keyno].nbits = strtoul (line+n+3, NULL, 10);
793               else if (algo == PUBKEY_ALGO_ECDH || algo == PUBKEY_ALGO_ECDSA
794                        || algo == PUBKEY_ALGO_EDDSA)
795                 {
796                   parm->key_attr[keyno].curve =
797                     openpgp_is_curve_supported (line + n, NULL, NULL);
798                 }
799             }
800         }
801       break;
802
803     case 9:
804       if (!memcmp (keyword, "DISP-NAME", keywordlen))
805         {
806           xfree (parm->disp_name);
807           parm->disp_name = unescape_status_string (line);
808         }
809       else if (!memcmp (keyword, "DISP-LANG", keywordlen))
810         {
811           xfree (parm->disp_lang);
812           parm->disp_lang = unescape_status_string (line);
813         }
814       else if (!memcmp (keyword, "CHV-USAGE", keywordlen))
815         {
816           unsigned int byte1, byte2;
817
818           byte1 = byte2 = 0;
819           sscanf (line, "%x %x", &byte1, &byte2);
820           parm->chvusage[0] = byte1;
821           parm->chvusage[1] = byte2;
822         }
823       break;
824
825     case 10:
826       if (!memcmp (keyword, "PUBKEY-URL", keywordlen))
827         {
828           xfree (parm->pubkey_url);
829           parm->pubkey_url = unescape_status_string (line);
830         }
831       else if (!memcmp (keyword, "LOGIN-DATA", keywordlen))
832         {
833           xfree (parm->login_data);
834           parm->login_data = unescape_status_string (line);
835         }
836       else if (!memcmp (keyword, "CHV-STATUS", keywordlen))
837         {
838           char *p, *buf;
839
840           buf = p = unescape_status_string (line);
841           if (buf)
842             while (spacep (p))
843               p++;
844
845           if (!buf)
846             ;
847           else if (parm->apptype == APP_TYPE_OPENPGP)
848             {
849               parm->chv1_cached = atoi (p);
850               while (*p && !spacep (p))
851                 p++;
852               while (spacep (p))
853                 p++;
854               for (i=0; *p && i < 3; i++)
855                 {
856                   parm->chvmaxlen[i] = atoi (p);
857                   while (*p && !spacep (p))
858                     p++;
859                   while (spacep (p))
860                     p++;
861                 }
862               for (i=0; *p && i < 3; i++)
863                 {
864                   parm->chvinfo[i] = atoi (p);
865                   while (*p && !spacep (p))
866                     p++;
867                   while (spacep (p))
868                     p++;
869                 }
870             }
871           else if (parm->apptype == APP_TYPE_PIV)
872             {
873               for (i=0; *p && i < DIM (parm->chvinfo); i++)
874                 {
875                   parm->chvinfo[i] = atoi (p);
876                   while (*p && !spacep (p))
877                     p++;
878                   while (spacep (p))
879                     p++;
880                 }
881             }
882
883           xfree (buf);
884         }
885       else if (!memcmp (keyword, "APPVERSION", keywordlen))
886         {
887           unsigned int val = 0;
888
889           sscanf (line, "%x", &val);
890           parm->appversion = val;
891         }
892       break;
893
894     case 11:
895       if (!memcmp (keyword, "SIG-COUNTER", keywordlen))
896         {
897           parm->sig_counter = strtoul (line, NULL, 0);
898         }
899       else if (!memcmp (keyword, "KEYPAIRINFO", keywordlen))
900         {
901           /* The format of such a line is:
902            *   KEYPAIRINFO <hexgrip> <keyref> [usage]
903            */
904           char *hexgrp, *usage;
905
906           line_buffer = pline = xstrdup (line);
907
908           hexgrp = pline;
909           while (*pline && !spacep (pline))
910             pline++;
911           while (spacep (pline))
912             pline++;
913
914           keyref = pline;
915           while (*pline && !spacep (pline))
916             pline++;
917           if (*pline)
918             {
919               *pline++ = 0;
920               while (spacep (pline))
921                 pline++;
922               usage = pline;
923               while (*pline && !spacep (pline))
924                 pline++;
925               *pline = 0;
926             }
927           else
928             usage = "";
929
930           /* Check whether we already have an item for the keyref.  */
931           kinfo = find_kinfo (parm, keyref);
932           if (!kinfo)  /* New entry.  */
933             kinfo = create_kinfo (parm, keyref);
934           else /* Existing entry - clear grip and usage  */
935             {
936               memset (kinfo->grip, 0, sizeof kinfo->grip);
937               kinfo->usage = 0;
938             }
939
940           /* Set or update the grip.  Note that due to the
941            * calloc/memset an erroneous too short grip will be nul
942            * padded on the right. */
943           unhexify_fpr (hexgrp, kinfo->grip, sizeof kinfo->grip);
944           /* Parse and set the usage.  */
945           for (; *usage; usage++)
946             {
947               switch (*usage)
948                 {
949                 case 's': kinfo->usage |= GCRY_PK_USAGE_SIGN; break;
950                 case 'c': kinfo->usage |= GCRY_PK_USAGE_CERT; break;
951                 case 'a': kinfo->usage |= GCRY_PK_USAGE_AUTH; break;
952                 case 'e': kinfo->usage |= GCRY_PK_USAGE_ENCR; break;
953                 }
954             }
955         }
956       else if (!memcmp (keyword, "CARDVERSION", keywordlen))
957         {
958           unsigned int val = 0;
959
960           sscanf (line, "%x", &val);
961           parm->cardversion = val;
962         }
963       break;
964
965     case 12:
966       if (!memcmp (keyword, "PRIVATE-DO-", 11)
967           && strchr("1234", keyword[11]))
968         {
969           int no = keyword[11] - '1';
970           log_assert (no >= 0 && no <= 3);
971           xfree (parm->private_do[no]);
972           parm->private_do[no] = unescape_status_string (line);
973         }
974       break;
975
976     case 13:
977       if (!memcmp (keyword, "$DISPSERIALNO", keywordlen))
978         {
979           xfree (parm->dispserialno);
980           parm->dispserialno = unescape_status_string (line);
981         }
982       break;
983
984     default:
985       /* Unknown.  */
986       break;
987     }
988
989   xfree (line_buffer);
990   return 0;
991 }
992
993
994 /* Call the scdaemon to learn about a smartcard.  This fills INFO
995  * with data from the card. */
996 gpg_error_t
997 scd_learn (card_info_t info)
998 {
999   gpg_error_t err;
1000   struct default_inq_parm_s parm;
1001   struct card_info_s dummyinfo;
1002
1003   if (!info)
1004     info = &dummyinfo;
1005
1006   memset (info, 0, sizeof *info);
1007   memset (&parm, 0, sizeof parm);
1008
1009   err = start_agent (0);
1010   if (err)
1011     return err;
1012
1013   parm.ctx = agent_ctx;
1014   err = assuan_transact (agent_ctx, "SCD LEARN --force",
1015                          dummy_data_cb, NULL, default_inq_cb, &parm,
1016                          learn_status_cb, info);
1017   /* Also try to get some other key attributes.  */
1018   if (!err)
1019     {
1020       info->initialized = 1;
1021
1022       err = scd_getattr ("KEY-ATTR", info);
1023       if (gpg_err_code (err) == GPG_ERR_INV_NAME
1024           || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_OPERATION)
1025         err = 0; /* Not implemented or GETATTR not supported.  */
1026       err = scd_getattr ("$DISPSERIALNO", info);
1027       if (gpg_err_code (err) == GPG_ERR_INV_NAME
1028           || gpg_err_code (err) == GPG_ERR_UNSUPPORTED_OPERATION)
1029         err = 0; /* Not implemented or GETATTR not supported.  */
1030     }
1031
1032   if (info == &dummyinfo)
1033     release_card_info (info);
1034
1035   return err;
1036 }
1037
1038
1039 /* Call the agent to retrieve a data object.  This function returns
1040  * the data in the same structure as used by the learn command.  It is
1041  * allowed to update such a structure using this command. */
1042 gpg_error_t
1043 scd_getattr (const char *name, struct card_info_s *info)
1044 {
1045   gpg_error_t err;
1046   char line[ASSUAN_LINELENGTH];
1047   struct default_inq_parm_s parm;
1048
1049   memset (&parm, 0, sizeof parm);
1050
1051   if (!*name)
1052     return gpg_error (GPG_ERR_INV_VALUE);
1053
1054   /* We assume that NAME does not need escaping. */
1055   if (12 + strlen (name) > DIM(line)-1)
1056     return gpg_error (GPG_ERR_TOO_LARGE);
1057   stpcpy (stpcpy (line, "SCD GETATTR "), name);
1058
1059   err = start_agent (0);
1060   if (err)
1061     return err;
1062
1063   parm.ctx = agent_ctx;
1064   err = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &parm,
1065                         learn_status_cb, info);
1066
1067   return err;
1068 }
1069
1070
1071 /* Send an setattr command to the SCdaemon.  */
1072 gpg_error_t
1073 scd_setattr (const char *name,
1074              const unsigned char *value, size_t valuelen)
1075 {
1076   gpg_error_t err;
1077   char *tmp;
1078   char *line = NULL;
1079   struct default_inq_parm_s parm;
1080
1081
1082   if (!*name || !valuelen)
1083     return gpg_error (GPG_ERR_INV_VALUE);
1084
1085   tmp = strconcat ("SCD SETATTR ", name, " ", NULL);
1086   if (!tmp)
1087     {
1088       err = gpg_error_from_syserror ();
1089       goto leave;
1090     }
1091   line = percent_data_escape (1, tmp, value, valuelen);
1092   xfree (tmp);
1093   if (!line)
1094     {
1095       err = gpg_error_from_syserror ();
1096       goto leave;
1097     }
1098
1099   if (strlen (line) + 10 > ASSUAN_LINELENGTH)
1100     {
1101       err = gpg_error (GPG_ERR_TOO_LARGE);
1102       goto leave;
1103     }
1104
1105   err = start_agent (0);
1106   if (err )
1107     goto leave;
1108
1109   memset (&parm, 0, sizeof parm);
1110   parm.ctx = agent_ctx;
1111   err = assuan_transact (agent_ctx, line, NULL, NULL,
1112                          default_inq_cb, &parm, NULL, NULL);
1113
1114  leave:
1115   xfree (line);
1116   return status_sc_op_failure (err);
1117 }
1118
1119
1120 \f
1121 /* Handle a CERTDATA inquiry.  Note, we only send the data,
1122  * assuan_transact takes care of flushing and writing the END
1123  * command. */
1124 static gpg_error_t
1125 inq_writecert_parms (void *opaque, const char *line)
1126 {
1127   gpg_error_t err;
1128   struct writecert_parm_s *parm = opaque;
1129
1130   if (has_leading_keyword (line, "CERTDATA"))
1131     {
1132       err = assuan_send_data (parm->dflt->ctx,
1133                               parm->certdata, parm->certdatalen);
1134     }
1135   else
1136     err = default_inq_cb (parm->dflt, line);
1137
1138   return err;
1139 }
1140
1141
1142 /* Send a WRITECERT command to the SCdaemon. */
1143 gpg_error_t
1144 scd_writecert (const char *certidstr,
1145                const unsigned char *certdata, size_t certdatalen)
1146 {
1147   gpg_error_t err;
1148   char line[ASSUAN_LINELENGTH];
1149   struct writecert_parm_s parms;
1150   struct default_inq_parm_s dfltparm;
1151
1152   memset (&dfltparm, 0, sizeof dfltparm);
1153
1154   err = start_agent (0);
1155   if (err)
1156     return err;
1157
1158   memset (&parms, 0, sizeof parms);
1159
1160   snprintf (line, sizeof line, "SCD WRITECERT %s", certidstr);
1161   dfltparm.ctx = agent_ctx;
1162   parms.dflt = &dfltparm;
1163   parms.certdata = certdata;
1164   parms.certdatalen = certdatalen;
1165
1166   err = assuan_transact (agent_ctx, line, NULL, NULL,
1167                          inq_writecert_parms, &parms, NULL, NULL);
1168
1169   return status_sc_op_failure (err);
1170 }
1171
1172
1173 \f
1174 /* Send a WRITEKEY command to the agent (so that the agent can fetch
1175  * the key to write).  KEYGRIP is the hexified keygrip of the source
1176  * key which will be written to tye slot KEYREF.  FORCE must be true
1177  * to overwrite an existing key.  */
1178 gpg_error_t
1179 scd_writekey (const char *keyref, int force, const char *keygrip)
1180 {
1181   gpg_error_t err;
1182   struct default_inq_parm_s parm;
1183   char line[ASSUAN_LINELENGTH];
1184
1185   memset (&parm, 0, sizeof parm);
1186
1187   err = start_agent (0);
1188   if (err)
1189     return err;
1190
1191   /* Note: We don't send the s/n but "-" because gpg-agent has
1192    * currently no use for it. */
1193   /* FIXME: For OpenPGP we should provide the creation time.  */
1194   snprintf (line, sizeof line, "KEYTOCARD%s %s - %s",
1195             force? " --force":"", keygrip, keyref);
1196   err = assuan_transact (agent_ctx, line, NULL, NULL,
1197                          default_inq_cb, &parm, NULL, NULL);
1198
1199   return status_sc_op_failure (err);
1200 }
1201
1202
1203 \f
1204 /* Status callback for the SCD GENKEY command. */
1205 static gpg_error_t
1206 scd_genkey_cb (void *opaque, const char *line)
1207 {
1208   u32 *createtime = opaque;
1209   const char *keyword = line;
1210   int keywordlen;
1211
1212   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1213     ;
1214   while (spacep (line))
1215     line++;
1216
1217  if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
1218     {
1219       if (createtime)
1220         *createtime = (u32)strtoul (line, NULL, 10);
1221     }
1222   else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
1223     {
1224       gnupg_status_printf (STATUS_PROGRESS, "%s", line);
1225     }
1226
1227   return 0;
1228 }
1229
1230 /* Send a GENKEY command to the SCdaemon.  If *CREATETIME is not 0,
1231  * the value will be passed to SCDAEMON with --timestamp option so that
1232  * the key is created with this.  Otherwise, timestamp was generated by
1233  * SCDEAMON.  On success, creation time is stored back to
1234  * CREATETIME.  */
1235 gpg_error_t
1236 scd_genkey (const char *keyref, int force, const char *algo, u32 *createtime)
1237 {
1238   gpg_error_t err;
1239   char line[ASSUAN_LINELENGTH];
1240   gnupg_isotime_t tbuf;
1241   struct default_inq_parm_s dfltparm;
1242
1243   memset (&dfltparm, 0, sizeof dfltparm);
1244
1245   err = start_agent (0);
1246   if (err)
1247     return err;
1248
1249   if (createtime && *createtime)
1250     epoch2isotime (tbuf, *createtime);
1251   else
1252     *tbuf = 0;
1253
1254   snprintf (line, sizeof line, "SCD GENKEY %s%s %s %s%s -- %s",
1255             *tbuf? "--timestamp=":"", tbuf,
1256             force? "--force":"",
1257             algo? "--algo=":"",
1258             algo? algo:"",
1259             keyref);
1260
1261   dfltparm.ctx = agent_ctx;
1262   err = assuan_transact (agent_ctx, line,
1263                          NULL, NULL, default_inq_cb, &dfltparm,
1264                          scd_genkey_cb, createtime);
1265
1266   return status_sc_op_failure (err);
1267 }
1268
1269
1270 \f
1271 /* Return the serial number of the card or an appropriate error.  The
1272  * serial number is returned as a hexstring.  If DEMAND is not NULL
1273  * the reader with the a card of the serial number DEMAND is
1274  * requested.  */
1275 gpg_error_t
1276 scd_serialno (char **r_serialno, const char *demand)
1277 {
1278   int err;
1279   char *serialno = NULL;
1280   char line[ASSUAN_LINELENGTH];
1281
1282   err = start_agent (START_AGENT_SUPPRESS_ERRORS);
1283   if (err)
1284     return err;
1285
1286   if (!demand)
1287     strcpy (line, "SCD SERIALNO");
1288   else
1289     snprintf (line, DIM(line), "SCD SERIALNO --demand=%s", demand);
1290
1291   err = assuan_transact (agent_ctx, line,
1292                          NULL, NULL, NULL, NULL,
1293                          get_serialno_cb, &serialno);
1294   if (err)
1295     {
1296       xfree (serialno);
1297       return err;
1298     }
1299
1300   if (r_serialno)
1301     *r_serialno = serialno;
1302   else
1303     xfree (serialno);
1304   return 0;
1305 }
1306
1307
1308 \f
1309 /* Send a READCERT command to the SCdaemon. */
1310 gpg_error_t
1311 scd_readcert (const char *certidstr, void **r_buf, size_t *r_buflen)
1312 {
1313   gpg_error_t err;
1314   char line[ASSUAN_LINELENGTH];
1315   membuf_t data;
1316   size_t len;
1317   struct default_inq_parm_s dfltparm;
1318
1319   memset (&dfltparm, 0, sizeof dfltparm);
1320
1321   *r_buf = NULL;
1322   err = start_agent (0);
1323   if (err)
1324     return err;
1325
1326   dfltparm.ctx = agent_ctx;
1327
1328   init_membuf (&data, 2048);
1329
1330   snprintf (line, sizeof line, "SCD READCERT %s", certidstr);
1331   err = assuan_transact (agent_ctx, line,
1332                          put_membuf_cb, &data,
1333                          default_inq_cb, &dfltparm,
1334                          NULL, NULL);
1335   if (err)
1336     {
1337       xfree (get_membuf (&data, &len));
1338       return err;
1339     }
1340
1341   *r_buf = get_membuf (&data, r_buflen);
1342   if (!*r_buf)
1343     return gpg_error_from_syserror ();
1344
1345   return 0;
1346 }
1347
1348
1349 \f
1350 /* Send a READKEY command to the SCdaemon.  On success a new
1351  * s-expression is stored at R_RESULT.  */
1352 gpg_error_t
1353 scd_readkey (const char *keyrefstr, gcry_sexp_t *r_result)
1354 {
1355   gpg_error_t err;
1356   char line[ASSUAN_LINELENGTH];
1357   membuf_t data;
1358   unsigned char *buf;
1359   size_t len, buflen;
1360
1361   *r_result = NULL;
1362   err = start_agent (0);
1363   if (err)
1364     return err;
1365
1366   init_membuf (&data, 1024);
1367   snprintf (line, DIM(line), "SCD READKEY %s", keyrefstr);
1368   err = assuan_transact (agent_ctx, line,
1369                          put_membuf_cb, &data,
1370                          NULL, NULL,
1371                          NULL, NULL);
1372   if (err)
1373     {
1374       xfree (get_membuf (&data, &len));
1375       return err;
1376     }
1377   buf = get_membuf (&data, &buflen);
1378   if (!buf)
1379     return gpg_error_from_syserror ();
1380
1381   err = gcry_sexp_new (r_result, buf, buflen, 0);
1382   xfree (buf);
1383
1384   return err;
1385 }
1386
1387
1388 \f
1389 /* Callback function for card_cardlist.  */
1390 static gpg_error_t
1391 card_cardlist_cb (void *opaque, const char *line)
1392 {
1393   struct card_cardlist_parm_s *parm = opaque;
1394   const char *keyword = line;
1395   int keywordlen;
1396
1397   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1398     ;
1399   while (spacep (line))
1400     line++;
1401
1402   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
1403     {
1404       const char *s;
1405       int n;
1406
1407       for (n=0,s=line; hexdigitp (s); s++, n++)
1408         ;
1409
1410       if (!n || (n&1) || *s)
1411         parm->error = gpg_error (GPG_ERR_ASS_PARAMETER);
1412       else
1413         add_to_strlist (&parm->list, line);
1414     }
1415
1416   return 0;
1417 }
1418
1419
1420 /* Return the serial numbers of all cards currently inserted.  */
1421 gpg_error_t
1422 scd_cardlist (strlist_t *result)
1423 {
1424   gpg_error_t err;
1425   struct card_cardlist_parm_s parm;
1426
1427   memset (&parm, 0, sizeof parm);
1428   *result = NULL;
1429
1430   err = start_agent (START_AGENT_SUPPRESS_ERRORS);
1431   if (err)
1432     return err;
1433
1434   err = assuan_transact (agent_ctx, "SCD GETINFO card_list",
1435                          NULL, NULL, NULL, NULL,
1436                          card_cardlist_cb, &parm);
1437   if (!err && parm.error)
1438     err = parm.error;
1439
1440   if (!err)
1441     *result = parm.list;
1442   else
1443     free_strlist (parm.list);
1444
1445   return err;
1446 }
1447
1448
1449 \f
1450 /* Change the PIN of an OpenPGP card or reset the retry counter.
1451  * CHVNO 1: Change the PIN
1452  *       2: For v1 cards: Same as 1.
1453  *          For v2 cards: Reset the PIN using the Reset Code.
1454  *       3: Change the admin PIN
1455  *     101: Set a new PIN and reset the retry counter
1456  *     102: For v1 cars: Same as 101.
1457  *          For v2 cards: Set a new Reset Code.
1458  */
1459 gpg_error_t
1460 scd_change_pin (const char *pinref, int reset_mode)
1461 {
1462   gpg_error_t err;
1463   char line[ASSUAN_LINELENGTH];
1464   struct default_inq_parm_s dfltparm;
1465
1466   memset (&dfltparm, 0, sizeof dfltparm);
1467
1468   err = start_agent (0);
1469   if (err)
1470     return err;
1471   dfltparm.ctx = agent_ctx;
1472
1473   snprintf (line, sizeof line, "SCD PASSWD%s %s",
1474             reset_mode? " --reset":"", pinref);
1475   err = assuan_transact (agent_ctx, line,
1476                          NULL, NULL,
1477                          default_inq_cb, &dfltparm,
1478                          NULL, NULL);
1479
1480   return status_sc_op_failure (err);
1481 }
1482
1483
1484 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
1485  * number of the card - optionally followed by the fingerprint;
1486  * however the fingerprint is ignored here. */
1487 gpg_error_t
1488 scd_checkpin (const char *serialno)
1489 {
1490   gpg_error_t err;
1491   char line[ASSUAN_LINELENGTH];
1492   struct default_inq_parm_s dfltparm;
1493
1494   memset (&dfltparm, 0, sizeof dfltparm);
1495
1496   err = start_agent (0);
1497   if (err)
1498     return err;
1499   dfltparm.ctx = agent_ctx;
1500
1501   snprintf (line, sizeof line, "SCD CHECKPIN %s", serialno);
1502   err = assuan_transact (agent_ctx, line,
1503                          NULL, NULL,
1504                          default_inq_cb, &dfltparm,
1505                          NULL, NULL);
1506   return status_sc_op_failure (err);
1507 }
1508
1509
1510 /* Return the S2K iteration count as computed by gpg-agent.  On error
1511  * print a warning and return a default value. */
1512 unsigned long
1513 agent_get_s2k_count (void)
1514 {
1515   gpg_error_t err;
1516   membuf_t data;
1517   char *buf;
1518   unsigned long count = 0;
1519
1520   err = start_agent (0);
1521   if (err)
1522     goto leave;
1523
1524   init_membuf (&data, 32);
1525   err = assuan_transact (agent_ctx, "GETINFO s2k_count",
1526                         put_membuf_cb, &data,
1527                         NULL, NULL, NULL, NULL);
1528   if (err)
1529     xfree (get_membuf (&data, NULL));
1530   else
1531     {
1532       put_membuf (&data, "", 1);
1533       buf = get_membuf (&data, NULL);
1534       if (!buf)
1535         err = gpg_error_from_syserror ();
1536       else
1537         {
1538           count = strtoul (buf, NULL, 10);
1539           xfree (buf);
1540         }
1541     }
1542
1543  leave:
1544   if (err || count < 65536)
1545     {
1546       /* Don't print an error if an older agent is used.  */
1547       if (err && gpg_err_code (err) != GPG_ERR_ASS_PARAMETER)
1548         log_error (_("problem with the agent: %s\n"), gpg_strerror (err));
1549
1550       /* Default to 65536 which was used up to 2.0.13.  */
1551       count = 65536;
1552     }
1553
1554   return count;
1555 }