gpg: Limit keysize for unattended key generation to useful values.
[gnupg.git] / g10 / call-agent.c
1 /* call-agent.c - Divert GPG operations to the agent.
2  * Copyright (C) 2001, 2002, 2003, 2006, 2007,
3  *               2008, 2009 Free Software Foundation, Inc.
4  * Copyright (C) 2014  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 <http://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <time.h>
29 #include <assert.h>
30 #ifdef HAVE_LOCALE_H
31 #include <locale.h>
32 #endif
33
34 #include "gpg.h"
35 #include <assuan.h>
36 #include "util.h"
37 #include "membuf.h"
38 #include "options.h"
39 #include "i18n.h"
40 #include "asshelp.h"
41 #include "sysutils.h"
42 #include "call-agent.h"
43 #include "status.h"
44
45 #ifndef DBG_ASSUAN
46 # define DBG_ASSUAN 1
47 #endif
48
49 static assuan_context_t agent_ctx = NULL;
50 static int did_early_card_test;
51
52 struct cipher_parm_s
53 {
54   assuan_context_t ctx;
55   const char *ciphertext;
56   size_t ciphertextlen;
57 };
58
59 struct writecert_parm_s
60 {
61   assuan_context_t ctx;
62   const unsigned char *certdata;
63   size_t certdatalen;
64 };
65
66 struct writekey_parm_s
67 {
68   assuan_context_t ctx;
69   const unsigned char *keydata;
70   size_t keydatalen;
71 };
72
73 struct genkey_parm_s
74 {
75   assuan_context_t ctx;
76   const char *sexp;
77   size_t sexplen;
78 };
79
80 struct scd_genkey_parm_s
81 {
82   struct agent_card_genkey_s *cgk;
83   char *savedbytes;     /* Malloced space to save key parameter chunks.  */
84 };
85
86
87 static gpg_error_t learn_status_cb (void *opaque, const char *line);
88
89
90 \f
91 /* If RC is not 0, write an appropriate status message. */
92 static void
93 status_sc_op_failure (int rc)
94 {
95   switch (gpg_err_code (rc))
96     {
97     case 0:
98       break;
99     case GPG_ERR_CANCELED:
100       write_status_text (STATUS_SC_OP_FAILURE, "1");
101       break;
102     case GPG_ERR_BAD_PIN:
103       write_status_text (STATUS_SC_OP_FAILURE, "2");
104       break;
105     default:
106       write_status (STATUS_SC_OP_FAILURE);
107       break;
108     }
109 }
110
111
112 static gpg_error_t
113 membuf_data_cb (void *opaque, const void *buffer, size_t length)
114 {
115   membuf_t *data = opaque;
116
117   if (buffer)
118     put_membuf (data, buffer, length);
119   return 0;
120 }
121
122
123 /* This is the default inquiry callback.  It mainly handles the
124    Pinentry notifications.  */
125 static gpg_error_t
126 default_inq_cb (void *opaque, const char *line)
127 {
128   (void)opaque;
129
130   if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
131     {
132       /* There is no working server mode yet thus we use
133          AllowSetForegroundWindow window right here.  We might want to
134          do this anyway in case gpg is called on the console. */
135       gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
136       /* We do not pass errors to avoid breaking other code.  */
137     }
138   else
139     log_debug ("ignoring gpg-agent inquiry `%s'\n", line);
140
141   return 0;
142 }
143
144
145 /* Check whether gnome-keyring hijacked the gpg-agent.  */
146 static void
147 check_hijacking (assuan_context_t ctx)
148 {
149   membuf_t mb;
150   char *string;
151
152   init_membuf (&mb, 64);
153
154   /* AGENT_ID is a command implemented by gnome-keyring-daemon.  IT
155      does not reatun any data but an OK line with a remark.  */
156   if (assuan_transact (ctx, "AGENT_ID",
157                        membuf_data_cb, &mb, NULL, NULL, NULL, NULL))
158     {
159       xfree (get_membuf (&mb, NULL));
160       return; /* Error - Probably not hijacked.  */
161     }
162   put_membuf (&mb, "", 1);
163   string = get_membuf (&mb, NULL);
164   if (!string || !*string)
165     {
166       /* Definitely hijacked - show a warning prompt.  */
167       static int shown;
168       const char warn1[] =
169         "The GNOME keyring manager hijacked the GnuPG agent.";
170       const char warn2[] =
171         "GnuPG will not work properly - please configure that "
172         "tool to not interfere with the GnuPG system!";
173       log_info ("WARNING: %s\n", warn1);
174       log_info ("WARNING: %s\n", warn2);
175       /*                 (GPG_ERR_SOURCRE_GPG, GPG_ERR_NO_AGENT) */
176       write_status_text (STATUS_ERROR, "check_hijacking 33554509");
177       xfree (string);
178       string = strconcat (warn1, "\n\n", warn2, NULL);
179       if (string && !shown && !opt.batch)
180         {
181           /* NB: The Pinentry based prompt will only work if a
182              gnome-keyring manager passes invalid commands on to the
183              original gpg-agent.  */
184           char *cmd, *cmdargs;
185
186           cmdargs = percent_plus_escape (string);
187           cmd = strconcat ("GET_CONFIRMATION ", cmdargs, NULL);
188           xfree (cmdargs);
189           if (cmd)
190             {
191               assuan_transact (ctx, cmd, NULL, NULL,
192                                default_inq_cb, NULL,
193                                NULL, NULL);
194               xfree (cmd);
195               shown = 1;
196             }
197         }
198     }
199   xfree (string);
200 }
201
202
203 /* Try to connect to the agent via socket or fork it off and work by
204    pipes.  Handle the server's initial greeting */
205 static int
206 start_agent (int for_card)
207 {
208   int rc;
209
210   /* Fixme: We need a context for each thread or serialize the access
211      to the agent. */
212   if (agent_ctx)
213     rc = 0;
214   else
215     {
216       rc = start_new_gpg_agent (&agent_ctx,
217                                 GPG_ERR_SOURCE_DEFAULT,
218                                 opt.homedir,
219                                 opt.agent_program,
220                                 opt.lc_ctype, opt.lc_messages,
221                                 opt.session_env,
222                                 opt.verbose, DBG_ASSUAN,
223                                 NULL, NULL);
224       if (!rc)
225         {
226           /* Tell the agent that we support Pinentry notifications.
227              No error checking so that it will work also with older
228              agents.  */
229           assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
230                            NULL, NULL, NULL, NULL, NULL, NULL);
231           check_hijacking (agent_ctx);
232         }
233     }
234
235   if (!rc && for_card && !did_early_card_test)
236     {
237       /* Request the serial number of the card for an early test.  */
238       struct agent_card_info_s info;
239
240       memset (&info, 0, sizeof info);
241       rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
242                             NULL, NULL, NULL, NULL,
243                             learn_status_cb, &info);
244       if (rc)
245         {
246           switch (gpg_err_code (rc))
247             {
248             case GPG_ERR_NOT_SUPPORTED:
249             case GPG_ERR_NO_SCDAEMON:
250               write_status_text (STATUS_CARDCTRL, "6");
251               break;
252             default:
253               write_status_text (STATUS_CARDCTRL, "4");
254               log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
255               break;
256             }
257         }
258
259       if (!rc && is_status_enabled () && info.serialno)
260         {
261           char *buf;
262
263           buf = xasprintf ("3 %s", info.serialno);
264           write_status_text (STATUS_CARDCTRL, buf);
265           xfree (buf);
266         }
267
268       agent_release_card_info (&info);
269
270       if (!rc)
271         did_early_card_test = 1;
272     }
273
274
275   return rc;
276 }
277
278
279 /* Return a new malloced string by unescaping the string S.  Escaping
280    is percent escaping and '+'/space mapping.  A binary nul will
281    silently be replaced by a 0xFF.  Function returns NULL to indicate
282    an out of memory status. */
283 static char *
284 unescape_status_string (const unsigned char *s)
285 {
286   return percent_plus_unescape (s, 0xff);
287 }
288
289
290 /* Take a 20 byte hexencoded string and put it into the the provided
291    20 byte buffer FPR in binary format. */
292 static int
293 unhexify_fpr (const char *hexstr, unsigned char *fpr)
294 {
295   const char *s;
296   int n;
297
298   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
299     ;
300   if (*s || (n != 40))
301     return 0; /* no fingerprint (invalid or wrong length). */
302   for (s=hexstr, n=0; *s; s += 2, n++)
303     fpr[n] = xtoi_2 (s);
304   return 1; /* okay */
305 }
306
307 /* Take the serial number from LINE and return it verbatim in a newly
308    allocated string.  We make sure that only hex characters are
309    returned. */
310 static char *
311 store_serialno (const char *line)
312 {
313   const char *s;
314   char *p;
315
316   for (s=line; hexdigitp (s); s++)
317     ;
318   p = xtrymalloc (s + 1 - line);
319   if (p)
320     {
321       memcpy (p, line, s-line);
322       p[s-line] = 0;
323     }
324   return p;
325 }
326
327
328 \f
329 /* This is a dummy data line callback.  */
330 static gpg_error_t
331 dummy_data_cb (void *opaque, const void *buffer, size_t length)
332 {
333   (void)opaque;
334   (void)buffer;
335   (void)length;
336   return 0;
337 }
338
339 /* A simple callback used to return the serialnumber of a card.  */
340 static gpg_error_t
341 get_serialno_cb (void *opaque, const char *line)
342 {
343   char **serialno = opaque;
344   const char *keyword = line;
345   const char *s;
346   int keywordlen, n;
347
348   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
349     ;
350   while (spacep (line))
351     line++;
352
353   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
354     {
355       if (*serialno)
356         return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
357       for (n=0,s=line; hexdigitp (s); s++, n++)
358         ;
359       if (!n || (n&1)|| !(spacep (s) || !*s) )
360         return gpg_error (GPG_ERR_ASS_PARAMETER);
361       *serialno = xtrymalloc (n+1);
362       if (!*serialno)
363         return out_of_core ();
364       memcpy (*serialno, line, n);
365       (*serialno)[n] = 0;
366     }
367
368   return 0;
369 }
370
371
372 /* Release the card info structure INFO. */
373 void
374 agent_release_card_info (struct agent_card_info_s *info)
375 {
376   if (!info)
377     return;
378
379   xfree (info->serialno); info->serialno = NULL;
380   xfree (info->apptype); info->apptype = NULL;
381   xfree (info->disp_name); info->disp_name = NULL;
382   xfree (info->disp_lang); info->disp_lang = NULL;
383   xfree (info->pubkey_url); info->pubkey_url = NULL;
384   xfree (info->login_data); info->login_data = NULL;
385   info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
386   info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
387 }
388
389 static gpg_error_t
390 learn_status_cb (void *opaque, const char *line)
391 {
392   struct agent_card_info_s *parm = opaque;
393   const char *keyword = line;
394   int keywordlen;
395   int i;
396
397   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
398     ;
399   while (spacep (line))
400     line++;
401
402   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
403     {
404       xfree (parm->serialno);
405       parm->serialno = store_serialno (line);
406       parm->is_v2 = (strlen (parm->serialno) >= 16
407                      && xtoi_2 (parm->serialno+12) >= 2 );
408     }
409   else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen))
410     {
411       xfree (parm->apptype);
412       parm->apptype = unescape_status_string (line);
413     }
414   else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
415     {
416       xfree (parm->disp_name);
417       parm->disp_name = unescape_status_string (line);
418     }
419   else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
420     {
421       xfree (parm->disp_lang);
422       parm->disp_lang = unescape_status_string (line);
423     }
424   else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
425     {
426       parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
427     }
428   else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
429     {
430       xfree (parm->pubkey_url);
431       parm->pubkey_url = unescape_status_string (line);
432     }
433   else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
434     {
435       xfree (parm->login_data);
436       parm->login_data = unescape_status_string (line);
437     }
438   else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
439     {
440       parm->sig_counter = strtoul (line, NULL, 0);
441     }
442   else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
443     {
444       char *p, *buf;
445
446       buf = p = unescape_status_string (line);
447       if (buf)
448         {
449           while (spacep (p))
450             p++;
451           parm->chv1_cached = atoi (p);
452           while (*p && !spacep (p))
453             p++;
454           while (spacep (p))
455             p++;
456           for (i=0; *p && i < 3; i++)
457             {
458               parm->chvmaxlen[i] = atoi (p);
459               while (*p && !spacep (p))
460                 p++;
461               while (spacep (p))
462                 p++;
463             }
464           for (i=0; *p && i < 3; i++)
465             {
466               parm->chvretry[i] = atoi (p);
467               while (*p && !spacep (p))
468                 p++;
469               while (spacep (p))
470                 p++;
471             }
472           xfree (buf);
473         }
474     }
475   else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen))
476     {
477       char *p, *p2, *buf;
478       int abool;
479
480       buf = p = unescape_status_string (line);
481       if (buf)
482         {
483           for (p = strtok (buf, " "); p; p = strtok (NULL, " "))
484             {
485               p2 = strchr (p, '=');
486               if (p2)
487                 {
488                   *p2++ = 0;
489                   abool = (*p2 == '1');
490                   if (!strcmp (p, "ki"))
491                     parm->extcap.ki = abool;
492                   else if (!strcmp (p, "aac"))
493                     parm->extcap.aac = abool;
494                 }
495             }
496           xfree (buf);
497         }
498     }
499   else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
500     {
501       int no = atoi (line);
502       while (*line && !spacep (line))
503         line++;
504       while (spacep (line))
505         line++;
506       if (no == 1)
507         parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
508       else if (no == 2)
509         parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
510       else if (no == 3)
511         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
512     }
513   else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
514     {
515       int no = atoi (line);
516       while (* line && !spacep (line))
517         line++;
518       while (spacep (line))
519         line++;
520       if (no == 1)
521         parm->fpr1time = strtoul (line, NULL, 10);
522       else if (no == 2)
523         parm->fpr2time = strtoul (line, NULL, 10);
524       else if (no == 3)
525         parm->fpr3time = strtoul (line, NULL, 10);
526     }
527   else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
528     {
529       int no = atoi (line);
530       while (*line && !spacep (line))
531         line++;
532       while (spacep (line))
533         line++;
534       if (no == 1)
535         parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
536       else if (no == 2)
537         parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
538       else if (no == 3)
539         parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
540     }
541   else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
542     {
543       int keyno, algo, nbits;
544
545       sscanf (line, "%d %d %d", &keyno, &algo, &nbits);
546       keyno--;
547       if (keyno >= 0 && keyno < DIM (parm->key_attr))
548         {
549           parm->key_attr[keyno].algo = algo;
550           parm->key_attr[keyno].nbits = nbits;
551         }
552     }
553
554   return 0;
555 }
556
557 /* Call the agent to learn about a smartcard */
558 int
559 agent_learn (struct agent_card_info_s *info)
560 {
561   int rc;
562
563   rc = start_agent (1);
564   if (rc)
565     return rc;
566
567   /* Send the serialno command to initialize the connection.  We don't
568      care about the data returned.  If the card has already been
569      initialized, this is a very fast command.  The main reason we
570      need to do this here is to handle a card removed case so that an
571      "l" command in --card-edit can be used to show ta newly inserted
572      card.  We request the openpgp card because that is what we
573      expect. */
574   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
575                         NULL, NULL, NULL, NULL, NULL, NULL);
576   if (rc)
577     return rc;
578
579
580   memset (info, 0, sizeof *info);
581   rc = assuan_transact (agent_ctx, "SCD LEARN --force",
582                         dummy_data_cb, NULL, default_inq_cb, NULL,
583                         learn_status_cb, info);
584   /* Also try to get the key attributes.  */
585   if (!rc)
586     agent_scd_getattr ("KEY-ATTR", info);
587
588   return rc;
589 }
590
591 /* Call the agent to retrieve a data object.  This function returns
592    the data in the same structure as used by the learn command.  It is
593    allowed to update such a structure using this commmand. */
594 int
595 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
596 {
597   int rc;
598   char line[ASSUAN_LINELENGTH];
599
600   if (!*name)
601     return gpg_error (GPG_ERR_INV_VALUE);
602
603   /* We assume that NAME does not need escaping. */
604   if (12 + strlen (name) > DIM(line)-1)
605     return gpg_error (GPG_ERR_TOO_LARGE);
606   stpcpy (stpcpy (line, "SCD GETATTR "), name);
607
608   rc = start_agent (1);
609   if (rc)
610     return rc;
611
612   rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
613                         learn_status_cb, info);
614
615   return rc;
616 }
617
618 \f
619 /* Send an setattr command to the SCdaemon.  SERIALNO is not actually
620    used here but required by gpg 1.4's implementation of this code in
621    cardglue.c. */
622 int
623 agent_scd_setattr (const char *name,
624                    const unsigned char *value, size_t valuelen,
625                    const char *serialno)
626 {
627   int rc;
628   char line[ASSUAN_LINELENGTH];
629   char *p;
630
631   (void)serialno;
632
633   if (!*name || !valuelen)
634     return gpg_error (GPG_ERR_INV_VALUE);
635
636   /* We assume that NAME does not need escaping. */
637   if (12 + strlen (name) > DIM(line)-1)
638     return gpg_error (GPG_ERR_TOO_LARGE);
639
640   p = stpcpy (stpcpy (line, "SCD SETATTR "), name);
641   *p++ = ' ';
642   for (; valuelen; value++, valuelen--)
643     {
644       if (p >= line + DIM(line)-5 )
645         return gpg_error (GPG_ERR_TOO_LARGE);
646       if (*value < ' ' || *value == '+' || *value == '%')
647         {
648           sprintf (p, "%%%02X", *value);
649           p += 3;
650         }
651       else if (*value == ' ')
652         *p++ = '+';
653       else
654         *p++ = *value;
655     }
656   *p = 0;
657
658   rc = start_agent (1);
659   if (!rc)
660     {
661       rc = assuan_transact (agent_ctx, line, NULL, NULL,
662                             default_inq_cb, NULL, NULL, NULL);
663     }
664
665   status_sc_op_failure (rc);
666   return rc;
667 }
668
669
670 \f
671 /* Handle a CERTDATA inquiry.  Note, we only send the data,
672    assuan_transact takes care of flushing and writing the END
673    command. */
674 static gpg_error_t
675 inq_writecert_parms (void *opaque, const char *line)
676 {
677   int rc;
678   struct writecert_parm_s *parm = opaque;
679
680   if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
681     {
682       rc = assuan_send_data (parm->ctx, parm->certdata, parm->certdatalen);
683     }
684   else
685     rc = default_inq_cb (opaque, line);
686
687   return rc;
688 }
689
690
691 /* Send a WRITECERT command to the SCdaemon. */
692 int
693 agent_scd_writecert (const char *certidstr,
694                      const unsigned char *certdata, size_t certdatalen)
695 {
696   int rc;
697   char line[ASSUAN_LINELENGTH];
698   struct writecert_parm_s parms;
699
700   rc = start_agent (1);
701   if (rc)
702     return rc;
703
704   memset (&parms, 0, sizeof parms);
705
706   snprintf (line, DIM(line)-1, "SCD WRITECERT %s", certidstr);
707   line[DIM(line)-1] = 0;
708   parms.ctx = agent_ctx;
709   parms.certdata = certdata;
710   parms.certdatalen = certdatalen;
711
712   rc = assuan_transact (agent_ctx, line, NULL, NULL,
713                         inq_writecert_parms, &parms, NULL, NULL);
714
715   return rc;
716 }
717
718
719 \f
720 /* Handle a KEYDATA inquiry.  Note, we only send the data,
721    assuan_transact takes care of flushing and writing the end */
722 static gpg_error_t
723 inq_writekey_parms (void *opaque, const char *line)
724 {
725   int rc;
726   struct writekey_parm_s *parm = opaque;
727
728   if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
729     {
730       rc = assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
731     }
732   else
733     rc = default_inq_cb (opaque, line);
734
735   return rc;
736 }
737
738
739 /* Send a WRITEKEY command to the SCdaemon. */
740 int
741 agent_scd_writekey (int keyno, const char *serialno,
742                     const unsigned char *keydata, size_t keydatalen)
743 {
744   int rc;
745   char line[ASSUAN_LINELENGTH];
746   struct writekey_parm_s parms;
747
748   (void)serialno;
749
750   rc = start_agent (1);
751   if (rc)
752     return rc;
753
754   memset (&parms, 0, sizeof parms);
755
756   snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
757   line[DIM(line)-1] = 0;
758   parms.ctx = agent_ctx;
759   parms.keydata = keydata;
760   parms.keydatalen = keydatalen;
761
762   rc = assuan_transact (agent_ctx, line, NULL, NULL,
763                         inq_writekey_parms, &parms, NULL, NULL);
764
765   status_sc_op_failure (rc);
766   return rc;
767 }
768
769
770 \f
771 static gpg_error_t
772 scd_genkey_cb_append_savedbytes (struct scd_genkey_parm_s *parm,
773                                  const char *line)
774 {
775   gpg_error_t err = 0;
776   char *p;
777
778   if (!parm->savedbytes)
779     {
780       parm->savedbytes = xtrystrdup (line);
781       if (!parm->savedbytes)
782         err = gpg_error_from_syserror ();
783     }
784   else
785     {
786       p = xtrymalloc (strlen (parm->savedbytes) + strlen (line) + 1);
787       if (!p)
788         err = gpg_error_from_syserror ();
789       else
790         {
791           strcpy (stpcpy (p, parm->savedbytes), line);
792           xfree (parm->savedbytes);
793           parm->savedbytes = p;
794         }
795     }
796
797   return err;
798 }
799
800
801 /* Status callback for the SCD GENKEY command. */
802 static gpg_error_t
803 scd_genkey_cb (void *opaque, const char *line)
804 {
805   struct scd_genkey_parm_s *parm = opaque;
806   const char *keyword = line;
807   int keywordlen;
808   gpg_error_t rc = 0;
809
810   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
811     ;
812   while (spacep (line))
813     line++;
814
815   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
816     {
817       parm->cgk->fprvalid = unhexify_fpr (line, parm->cgk->fpr);
818     }
819   else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
820     {
821       gcry_mpi_t a;
822       const char *name = line;
823
824       while (*line && !spacep (line))
825         line++;
826       while (spacep (line))
827         line++;
828
829       if (*name == '-' && spacep (name+1))
830         rc = scd_genkey_cb_append_savedbytes (parm, line);
831       else
832         {
833           if (parm->savedbytes)
834             {
835               rc = scd_genkey_cb_append_savedbytes (parm, line);
836               if (!rc)
837                 rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX,
838                                     parm->savedbytes, 0, NULL);
839             }
840           else
841             rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
842           if (rc)
843             log_error ("error parsing received key data: %s\n",
844                        gpg_strerror (rc));
845           else if (*name == 'n' && spacep (name+1))
846             parm->cgk->n = a;
847           else if (*name == 'e' && spacep (name+1))
848             parm->cgk->e = a;
849           else
850             {
851               log_info ("unknown parameter name in received key data\n");
852               gcry_mpi_release (a);
853               rc = gpg_error (GPG_ERR_INV_PARAMETER);
854             }
855
856           xfree (parm->savedbytes);
857           parm->savedbytes = NULL;
858         }
859     }
860   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
861     {
862       parm->cgk->created_at = (u32)strtoul (line, NULL, 10);
863     }
864   else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
865     {
866       write_status_text (STATUS_PROGRESS, line);
867     }
868
869   return rc;
870 }
871
872 /* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
873    this implementation.  If CREATEDATE has been given, it will be
874    passed to SCDAEMON so that the key can be created with this
875    timestamp; note the user needs to use the returned timestamp as old
876    versions of scddaemon don't support this option.  */
877 int
878 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
879                   const char *serialno, u32 createtime)
880 {
881   int rc;
882   char line[ASSUAN_LINELENGTH];
883   gnupg_isotime_t tbuf;
884   struct scd_genkey_parm_s parms;
885
886   (void)serialno;
887
888   memset (&parms, 0, sizeof parms);
889   parms.cgk = info;
890
891   rc = start_agent (1);
892   if (rc)
893     return rc;
894
895   if (createtime)
896     epoch2isotime (tbuf, createtime);
897   else
898     *tbuf = 0;
899
900   memset (info, 0, sizeof *info);
901   snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
902             *tbuf? "--timestamp=":"", tbuf,
903             force? "--force":"",
904             keyno);
905   line[DIM(line)-1] = 0;
906
907   memset (info, 0, sizeof *info);
908   rc = assuan_transact (agent_ctx, line,
909                         NULL, NULL, default_inq_cb, NULL,
910                         scd_genkey_cb, &parms);
911
912   xfree (parms.savedbytes);
913
914   status_sc_op_failure (rc);
915   return rc;
916 }
917
918
919
920 \f
921 /* Issue an SCD SERIALNO openpgp command and if SERIALNO is not NULL
922    ask the user to insert the requested card.  */
923 gpg_error_t
924 select_openpgp (const char *serialno)
925 {
926   gpg_error_t err;
927
928   /* Send the serialno command to initialize the connection.  Without
929      a given S/N we don't care about the data returned.  If the card
930      has already been initialized, this is a very fast command.  We
931      request the openpgp card because that is what we expect.
932
933      Note that an opt.limit_card_insert_tries of 1 means: No tries at
934      all whereas 0 means do not limit the number of tries.  Due to the
935      sue of a pinentry prompt with a cancel option we use it here in a
936      boolean sense.  */
937   if (!serialno || opt.limit_card_insert_tries == 1)
938     err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
939                            NULL, NULL, NULL, NULL, NULL, NULL);
940   else
941     {
942       char *this_sn = NULL;
943       char *desc;
944       int ask;
945       char *want_sn;
946       char *p;
947
948       want_sn = xtrystrdup (serialno);
949       if (!want_sn)
950         return gpg_error_from_syserror ();
951       p = strchr (want_sn, '/');
952       if (p)
953         *p = 0;
954
955       do
956         {
957           ask = 0;
958           err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
959                                  NULL, NULL, NULL, NULL,
960                                  get_serialno_cb, &this_sn);
961           if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
962             ask = 1;
963           else if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
964             ask = 2;
965           else if (err)
966             ;
967           else if (this_sn)
968             {
969               if (strcmp (want_sn, this_sn))
970                 ask = 2;
971             }
972
973           xfree (this_sn);
974           this_sn = NULL;
975
976           if (ask)
977             {
978               char *formatted = NULL;
979               char *ocodeset = i18n_switchto_utf8 ();
980
981               if (!strncmp (want_sn, "D27600012401", 12)
982                   && strlen (want_sn) == 32 )
983                 formatted = xtryasprintf ("(%.4s) %.8s",
984                                           want_sn + 16, want_sn + 20);
985
986               err = 0;
987               desc = xtryasprintf
988                 ("%s:\n\n"
989                  "  \"%s\"",
990                  ask == 1
991                  ? _("Please insert the card with serial number")
992                  : _("Please remove the current card and "
993                      "insert the one with serial number"),
994                  formatted? formatted : want_sn);
995               if (!desc)
996                 err = gpg_error_from_syserror ();
997               xfree (formatted);
998               i18n_switchback (ocodeset);
999               if (!err)
1000                 err = gpg_agent_get_confirmation (desc);
1001               xfree (desc);
1002             }
1003         }
1004       while (ask && !err);
1005       xfree (want_sn);
1006     }
1007
1008   return err;
1009 }
1010
1011
1012 \f
1013 /* Helper returning a command option to describe the used hash
1014    algorithm.  See scd/command.c:cmd_pksign.  */
1015 static const char *
1016 hash_algo_option (int algo)
1017 {
1018   switch (algo)
1019     {
1020     case GCRY_MD_RMD160: return "--hash=rmd160";
1021     case GCRY_MD_SHA1  : return "--hash=sha1";
1022     case GCRY_MD_SHA224: return "--hash=sha224";
1023     case GCRY_MD_SHA256: return "--hash=sha256";
1024     case GCRY_MD_SHA384: return "--hash=sha384";
1025     case GCRY_MD_SHA512: return "--hash=sha512";
1026     case GCRY_MD_MD5   : return "--hash=md5";
1027     default:             return "";
1028     }
1029 }
1030
1031 /* Send a sign command to the scdaemon via gpg-agent's pass thru
1032    mechanism. */
1033 int
1034 agent_scd_pksign (const char *serialno, int hashalgo,
1035                   const unsigned char *indata, size_t indatalen,
1036                   unsigned char **r_buf, size_t *r_buflen)
1037 {
1038   int rc, i;
1039   char *p, line[ASSUAN_LINELENGTH];
1040   membuf_t data;
1041   size_t len;
1042
1043   /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
1044
1045   *r_buf = NULL;
1046   *r_buflen = 0;
1047
1048   rc = start_agent (1);
1049   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
1050       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
1051     rc = 0; /* We check later.  */
1052   if (rc)
1053     return rc;
1054
1055   if (indatalen*2 + 50 > DIM(line))
1056     return gpg_error (GPG_ERR_GENERAL);
1057
1058   rc = select_openpgp (serialno);
1059   if (rc)
1060     return rc;
1061
1062   sprintf (line, "SCD SETDATA ");
1063   p = line + strlen (line);
1064   for (i=0; i < indatalen ; i++, p += 2 )
1065     sprintf (p, "%02X", indata[i]);
1066   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1067   if (rc)
1068     return rc;
1069
1070   init_membuf (&data, 1024);
1071 #if 0
1072   if (!hashalgo) /* Temporary test hack. */
1073     snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
1074   else
1075 #endif
1076     snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s",
1077               hash_algo_option (hashalgo), serialno);
1078   line[DIM(line)-1] = 0;
1079   rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
1080                         default_inq_cb, NULL, NULL, NULL);
1081   if (rc)
1082     {
1083       xfree (get_membuf (&data, &len));
1084     }
1085   else
1086     *r_buf = get_membuf (&data, r_buflen);
1087
1088   status_sc_op_failure (rc);
1089   return rc;
1090 }
1091
1092
1093 /* Decrypt INDATA of length INDATALEN using the card identified by
1094    SERIALNO.  Return the plaintext in a newly allocated buffer stored
1095    at the address of R_BUF.
1096
1097    Note, we currently support only RSA or more exactly algorithms
1098    taking one input data element. */
1099 int
1100 agent_scd_pkdecrypt (const char *serialno,
1101                      const unsigned char *indata, size_t indatalen,
1102                      unsigned char **r_buf, size_t *r_buflen)
1103 {
1104   int rc, i;
1105   char *p, line[ASSUAN_LINELENGTH];
1106   membuf_t data;
1107   size_t len;
1108
1109   *r_buf = NULL;
1110   rc = start_agent (1);
1111   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
1112       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
1113     rc = 0; /* We check later.  */
1114   if (rc)
1115     return rc;
1116
1117   /* FIXME: use secure memory where appropriate */
1118
1119   rc = select_openpgp (serialno);
1120   if (rc)
1121     return rc;
1122
1123   for (len = 0; len < indatalen;)
1124     {
1125       p = stpcpy (line, "SCD SETDATA ");
1126       if (len)
1127         p = stpcpy (p, "--append ");
1128       for (i=0; len < indatalen && (i*2 < DIM(line)-50); i++, len++)
1129         {
1130           sprintf (p, "%02X", indata[len]);
1131           p += 2;
1132         }
1133       rc = assuan_transact (agent_ctx, line,
1134                             NULL, NULL, NULL, NULL, NULL, NULL);
1135       if (rc)
1136         return rc;
1137     }
1138
1139   init_membuf (&data, 1024);
1140   snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
1141   line[DIM(line)-1] = 0;
1142   rc = assuan_transact (agent_ctx, line,
1143                         membuf_data_cb, &data,
1144                         default_inq_cb, NULL, NULL, NULL);
1145   if (rc)
1146     {
1147       xfree (get_membuf (&data, &len));
1148     }
1149   else
1150     {
1151       *r_buf = get_membuf (&data, r_buflen);
1152       if (!*r_buf)
1153         rc = gpg_error (GPG_ERR_ENOMEM);
1154     }
1155
1156   status_sc_op_failure (rc);
1157   return rc;
1158 }
1159
1160
1161 \f
1162 /* Send a READCERT command to the SCdaemon. */
1163 int
1164 agent_scd_readcert (const char *certidstr,
1165                     void **r_buf, size_t *r_buflen)
1166 {
1167   int rc;
1168   char line[ASSUAN_LINELENGTH];
1169   membuf_t data;
1170   size_t len;
1171
1172   *r_buf = NULL;
1173   rc = start_agent (1);
1174   if (rc)
1175     return rc;
1176
1177   init_membuf (&data, 2048);
1178
1179   snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
1180   line[DIM(line)-1] = 0;
1181   rc = assuan_transact (agent_ctx, line,
1182                         membuf_data_cb, &data,
1183                         default_inq_cb, NULL, NULL, NULL);
1184   if (rc)
1185     {
1186       xfree (get_membuf (&data, &len));
1187       return rc;
1188     }
1189   *r_buf = get_membuf (&data, r_buflen);
1190   if (!*r_buf)
1191     return gpg_error (GPG_ERR_ENOMEM);
1192
1193   return 0;
1194 }
1195
1196
1197 \f
1198 /* Change the PIN of an OpenPGP card or reset the retry counter.
1199    CHVNO 1: Change the PIN
1200          2: For v1 cards: Same as 1.
1201             For v2 cards: Reset the PIN using the Reset Code.
1202          3: Change the admin PIN
1203        101: Set a new PIN and reset the retry counter
1204        102: For v1 cars: Same as 101.
1205             For v2 cards: Set a new Reset Code.
1206    SERIALNO is not used.
1207  */
1208 int
1209 agent_scd_change_pin (int chvno, const char *serialno)
1210 {
1211   int rc;
1212   char line[ASSUAN_LINELENGTH];
1213   const char *reset = "";
1214
1215   (void)serialno;
1216
1217   if (chvno >= 100)
1218     reset = "--reset";
1219   chvno %= 100;
1220
1221   rc = start_agent (1);
1222   if (rc)
1223     return rc;
1224
1225   snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
1226   line[DIM(line)-1] = 0;
1227   rc = assuan_transact (agent_ctx, line, NULL, NULL,
1228                         default_inq_cb, NULL, NULL, NULL);
1229   status_sc_op_failure (rc);
1230   return rc;
1231 }
1232
1233
1234 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
1235    number of the card - optionally followed by the fingerprint;
1236    however the fingerprint is ignored here. */
1237 int
1238 agent_scd_checkpin  (const char *serialno)
1239 {
1240   int rc;
1241   char line[ASSUAN_LINELENGTH];
1242
1243   rc = start_agent (1);
1244   if (rc)
1245     return rc;
1246
1247   snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
1248   line[DIM(line)-1] = 0;
1249   rc = assuan_transact (agent_ctx, line,
1250                         NULL, NULL,
1251                         default_inq_cb, NULL, NULL, NULL);
1252   status_sc_op_failure (rc);
1253   return rc;
1254 }
1255
1256
1257 /* Dummy function, only used by the gpg 1.4 implementation. */
1258 void
1259 agent_clear_pin_cache (const char *sn)
1260 {
1261   (void)sn;
1262 }
1263
1264
1265
1266 \f
1267 /* Note: All strings shall be UTF-8. On success the caller needs to
1268    free the string stored at R_PASSPHRASE. On error NULL will be
1269    stored at R_PASSPHRASE and an appropriate fpf error code
1270    returned. */
1271 gpg_error_t
1272 agent_get_passphrase (const char *cache_id,
1273                       const char *err_msg,
1274                       const char *prompt,
1275                       const char *desc_msg,
1276                       int repeat,
1277                       int check,
1278                       char **r_passphrase)
1279 {
1280   int rc;
1281   char line[ASSUAN_LINELENGTH];
1282   char *arg1 = NULL;
1283   char *arg2 = NULL;
1284   char *arg3 = NULL;
1285   char *arg4 = NULL;
1286   membuf_t data;
1287
1288   *r_passphrase = NULL;
1289
1290   rc = start_agent (0);
1291   if (rc)
1292     return rc;
1293
1294   /* Check that the gpg-agent understands the repeat option.  */
1295   if (assuan_transact (agent_ctx,
1296                        "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1297                        NULL, NULL, NULL, NULL, NULL, NULL))
1298     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1299
1300   if (cache_id && *cache_id)
1301     if (!(arg1 = percent_plus_escape (cache_id)))
1302       goto no_mem;
1303   if (err_msg && *err_msg)
1304     if (!(arg2 = percent_plus_escape (err_msg)))
1305       goto no_mem;
1306   if (prompt && *prompt)
1307     if (!(arg3 = percent_plus_escape (prompt)))
1308       goto no_mem;
1309   if (desc_msg && *desc_msg)
1310     if (!(arg4 = percent_plus_escape (desc_msg)))
1311       goto no_mem;
1312
1313   snprintf (line, DIM(line)-1,
1314             "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s",
1315             repeat,
1316             check? " --check --qualitybar":"",
1317             arg1? arg1:"X",
1318             arg2? arg2:"X",
1319             arg3? arg3:"X",
1320             arg4? arg4:"X");
1321   line[DIM(line)-1] = 0;
1322   xfree (arg1);
1323   xfree (arg2);
1324   xfree (arg3);
1325   xfree (arg4);
1326
1327   init_membuf_secure (&data, 64);
1328   rc = assuan_transact (agent_ctx, line,
1329                         membuf_data_cb, &data,
1330                         default_inq_cb, NULL, NULL, NULL);
1331
1332   if (rc)
1333     xfree (get_membuf (&data, NULL));
1334   else
1335     {
1336       put_membuf (&data, "", 1);
1337       *r_passphrase = get_membuf (&data, NULL);
1338       if (!*r_passphrase)
1339         rc = gpg_error_from_syserror ();
1340     }
1341   return rc;
1342  no_mem:
1343   rc = gpg_error_from_syserror ();
1344   xfree (arg1);
1345   xfree (arg2);
1346   xfree (arg3);
1347   xfree (arg4);
1348   return rc;
1349 }
1350
1351
1352 gpg_error_t
1353 agent_clear_passphrase (const char *cache_id)
1354 {
1355   int rc;
1356   char line[ASSUAN_LINELENGTH];
1357
1358   if (!cache_id || !*cache_id)
1359     return 0;
1360
1361   rc = start_agent (0);
1362   if (rc)
1363     return rc;
1364
1365   snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
1366   line[DIM(line)-1] = 0;
1367   return assuan_transact (agent_ctx, line, NULL, NULL,
1368                           default_inq_cb, NULL, NULL, NULL);
1369 }
1370
1371
1372 /* Ask the agent to pop up a confirmation dialog with the text DESC
1373    and an okay and cancel button. */
1374 gpg_error_t
1375 gpg_agent_get_confirmation (const char *desc)
1376 {
1377   int rc;
1378   char *tmp;
1379   char line[ASSUAN_LINELENGTH];
1380
1381   rc = start_agent (0);
1382   if (rc)
1383     return rc;
1384
1385   tmp = percent_plus_escape (desc);
1386   if (!tmp)
1387     return gpg_error_from_syserror ();
1388   snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", tmp);
1389   line[DIM(line)-1] = 0;
1390   xfree (tmp);
1391
1392   rc = assuan_transact (agent_ctx, line, NULL, NULL,
1393                         default_inq_cb, NULL, NULL, NULL);
1394   return rc;
1395 }
1396
1397
1398 /* Return the S2K iteration count as computed by gpg-agent.  */
1399 gpg_error_t
1400 agent_get_s2k_count (unsigned long *r_count)
1401 {
1402   gpg_error_t err;
1403   membuf_t data;
1404   char *buf;
1405
1406   *r_count = 0;
1407
1408   err = start_agent (0);
1409   if (err)
1410     return err;
1411
1412   init_membuf (&data, 32);
1413   err = assuan_transact (agent_ctx, "GETINFO s2k_count",
1414                         membuf_data_cb, &data,
1415                         NULL, NULL, NULL, NULL);
1416   if (err)
1417     xfree (get_membuf (&data, NULL));
1418   else
1419     {
1420       put_membuf (&data, "", 1);
1421       buf = get_membuf (&data, NULL);
1422       if (!buf)
1423         err = gpg_error_from_syserror ();
1424       else
1425         {
1426           *r_count = strtoul (buf, NULL, 10);
1427           xfree (buf);
1428         }
1429     }
1430   return err;
1431 }
1432