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