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