Fix a for a bug fix in the latest Libgcrypt.
[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
896 /* Helper returning a command option to describe the used hash
897    algorithm.  See scd/command.c:cmd_pksign.  */
898 static const char *
899 hash_algo_option (int algo)
900 {
901   switch (algo)
902     {
903     case GCRY_MD_RMD160: return "--hash=rmd160";
904     case GCRY_MD_SHA1  : return "--hash=sha1";
905     case GCRY_MD_SHA224: return "--hash=sha224";
906     case GCRY_MD_SHA256: return "--hash=sha256";
907     case GCRY_MD_SHA384: return "--hash=sha384";
908     case GCRY_MD_SHA512: return "--hash=sha512";
909     case GCRY_MD_MD5   : return "--hash=md5";
910     default:             return "";
911     }
912 }
913
914 /* Send a sign command to the scdaemon via gpg-agent's pass thru
915    mechanism. */
916 int
917 agent_scd_pksign (const char *serialno, int hashalgo,
918                   const unsigned char *indata, size_t indatalen,
919                   unsigned char **r_buf, size_t *r_buflen)
920 {
921   int rc, i;
922   char *p, line[ASSUAN_LINELENGTH];
923   membuf_t data;
924   size_t len;
925
926   /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
927
928   *r_buf = NULL;
929   *r_buflen = 0;
930
931   rc = start_agent (1);
932   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
933       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
934     rc = 0; /* We check later.  */
935   if (rc)
936     return rc;
937
938   if (indatalen*2 + 50 > DIM(line))
939     return gpg_error (GPG_ERR_GENERAL);
940
941   rc = select_openpgp (serialno);
942   if (rc)
943     return rc;
944
945   sprintf (line, "SCD SETDATA ");
946   p = line + strlen (line);
947   for (i=0; i < indatalen ; i++, p += 2 )
948     sprintf (p, "%02X", indata[i]);
949   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
950   if (rc)
951     return rc;
952
953   init_membuf (&data, 1024);
954 #if 0
955   if (!hashalgo) /* Temporary test hack. */
956     snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
957   else
958 #endif
959     snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s",
960               hash_algo_option (hashalgo), serialno);
961   line[DIM(line)-1] = 0;
962   rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
963                         default_inq_cb, NULL, NULL, NULL);
964   if (rc)
965     {
966       xfree (get_membuf (&data, &len));
967     }
968   else
969     *r_buf = get_membuf (&data, r_buflen);
970
971   status_sc_op_failure (rc);
972   return rc;
973 }
974
975
976 /* Decrypt INDATA of length INDATALEN using the card identified by
977    SERIALNO.  Return the plaintext in a nwly allocated buffer stored
978    at the address of R_BUF.
979
980    Note, we currently support only RSA or more exactly algorithms
981    taking one input data element. */
982 int
983 agent_scd_pkdecrypt (const char *serialno,
984                      const unsigned char *indata, size_t indatalen,
985                      unsigned char **r_buf, size_t *r_buflen)
986 {
987   int rc, i;
988   char *p, line[ASSUAN_LINELENGTH];
989   membuf_t data;
990   size_t len;
991
992   *r_buf = NULL;
993   rc = start_agent (1);
994   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
995       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
996     rc = 0; /* We check later.  */
997   if (rc)
998     return rc;
999
1000   /* FIXME: use secure memory where appropriate */
1001   if (indatalen*2 + 50 > DIM(line))
1002     return gpg_error (GPG_ERR_GENERAL);
1003
1004   rc = select_openpgp (serialno);
1005   if (rc)
1006     return rc;
1007   
1008   sprintf (line, "SCD SETDATA ");
1009   p = line + strlen (line);
1010   for (i=0; i < indatalen ; i++, p += 2 )
1011     sprintf (p, "%02X", indata[i]);
1012   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1013   if (rc)
1014     return rc;
1015
1016   init_membuf (&data, 1024);
1017   snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
1018   line[DIM(line)-1] = 0;
1019   rc = assuan_transact (agent_ctx, line,
1020                         membuf_data_cb, &data,
1021                         default_inq_cb, NULL, NULL, NULL);
1022   if (rc)
1023     {
1024       xfree (get_membuf (&data, &len));
1025     }
1026   else
1027     {
1028       *r_buf = get_membuf (&data, r_buflen);
1029       if (!*r_buf)
1030         rc = gpg_error (GPG_ERR_ENOMEM);
1031     }
1032
1033   status_sc_op_failure (rc);
1034   return rc;
1035 }
1036
1037
1038 \f
1039 /* Send a READCERT command to the SCdaemon. */
1040 int 
1041 agent_scd_readcert (const char *certidstr,
1042                     void **r_buf, size_t *r_buflen)
1043 {
1044   int rc;
1045   char line[ASSUAN_LINELENGTH];
1046   membuf_t data;
1047   size_t len;
1048
1049   *r_buf = NULL;
1050   rc = start_agent (1);
1051   if (rc)
1052     return rc;
1053
1054   init_membuf (&data, 2048);
1055
1056   snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
1057   line[DIM(line)-1] = 0;
1058   rc = assuan_transact (agent_ctx, line,
1059                         membuf_data_cb, &data,
1060                         default_inq_cb, NULL, NULL, NULL);
1061   if (rc)
1062     {
1063       xfree (get_membuf (&data, &len));
1064       return rc;
1065     }
1066   *r_buf = get_membuf (&data, r_buflen);
1067   if (!*r_buf)
1068     return gpg_error (GPG_ERR_ENOMEM);
1069
1070   return 0;
1071 }
1072
1073
1074 \f
1075 /* Change the PIN of an OpenPGP card or reset the retry counter.
1076    CHVNO 1: Change the PIN
1077          2: For v1 cards: Same as 1.
1078             For v2 cards: Reset the PIN using the Reset Code.
1079          3: Change the admin PIN
1080        101: Set a new PIN and reset the retry counter
1081        102: For v1 cars: Same as 101.
1082             For v2 cards: Set a new Reset Code.
1083    SERIALNO is not used.
1084  */
1085 int
1086 agent_scd_change_pin (int chvno, const char *serialno)
1087 {
1088   int rc;
1089   char line[ASSUAN_LINELENGTH];
1090   const char *reset = "";
1091
1092   (void)serialno;
1093
1094   if (chvno >= 100)
1095     reset = "--reset";
1096   chvno %= 100;
1097
1098   rc = start_agent (1);
1099   if (rc)
1100     return rc;
1101
1102   snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
1103   line[DIM(line)-1] = 0;
1104   rc = assuan_transact (agent_ctx, line, NULL, NULL,
1105                         default_inq_cb, NULL, NULL, NULL);
1106   status_sc_op_failure (rc);
1107   return rc;
1108 }
1109
1110
1111 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
1112    number of the card - optionally followed by the fingerprint;
1113    however the fingerprint is ignored here. */
1114 int
1115 agent_scd_checkpin  (const char *serialno)
1116 {
1117   int rc;
1118   char line[ASSUAN_LINELENGTH];
1119
1120   rc = start_agent (1);
1121   if (rc)
1122     return rc;
1123
1124   snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
1125   line[DIM(line)-1] = 0;
1126   rc = assuan_transact (agent_ctx, line,
1127                         NULL, NULL,
1128                         default_inq_cb, NULL, NULL, NULL);
1129   status_sc_op_failure (rc);
1130   return rc;
1131 }
1132
1133
1134 /* Dummy function, only used by the gpg 1.4 implementation. */
1135 void
1136 agent_clear_pin_cache (const char *sn)
1137 {
1138   (void)sn;
1139 }
1140
1141
1142
1143 \f
1144 /* Note: All strings shall be UTF-8. On success the caller needs to
1145    free the string stored at R_PASSPHRASE. On error NULL will be
1146    stored at R_PASSPHRASE and an appropriate fpf error code
1147    returned. */
1148 gpg_error_t
1149 agent_get_passphrase (const char *cache_id,
1150                       const char *err_msg,
1151                       const char *prompt,
1152                       const char *desc_msg,
1153                       int repeat,
1154                       int check,
1155                       char **r_passphrase)
1156 {
1157   int rc;
1158   char line[ASSUAN_LINELENGTH];
1159   char *arg1 = NULL;
1160   char *arg2 = NULL;  
1161   char *arg3 = NULL; 
1162   char *arg4 = NULL;
1163   membuf_t data;
1164
1165   *r_passphrase = NULL;
1166
1167   rc = start_agent (0);
1168   if (rc)
1169     return rc;
1170
1171   /* Check that the gpg-agent understands the repeat option.  */
1172   if (assuan_transact (agent_ctx, 
1173                        "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1174                        NULL, NULL, NULL, NULL, NULL, NULL))
1175     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1176
1177   if (cache_id && *cache_id)
1178     if (!(arg1 = percent_plus_escape (cache_id)))
1179       goto no_mem;
1180   if (err_msg && *err_msg)
1181     if (!(arg2 = percent_plus_escape (err_msg)))
1182       goto no_mem;
1183   if (prompt && *prompt)
1184     if (!(arg3 = percent_plus_escape (prompt)))
1185       goto no_mem;
1186   if (desc_msg && *desc_msg)
1187     if (!(arg4 = percent_plus_escape (desc_msg)))
1188       goto no_mem;
1189
1190   snprintf (line, DIM(line)-1, 
1191             "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", 
1192             repeat, 
1193             check? " --check --qualitybar":"",
1194             arg1? arg1:"X",
1195             arg2? arg2:"X",
1196             arg3? arg3:"X",
1197             arg4? arg4:"X");
1198   line[DIM(line)-1] = 0;
1199   xfree (arg1);
1200   xfree (arg2);
1201   xfree (arg3);
1202   xfree (arg4);
1203
1204   init_membuf_secure (&data, 64);
1205   rc = assuan_transact (agent_ctx, line, 
1206                         membuf_data_cb, &data,
1207                         default_inq_cb, NULL, NULL, NULL);
1208
1209   if (rc)
1210     xfree (get_membuf (&data, NULL));
1211   else 
1212     {
1213       put_membuf (&data, "", 1);
1214       *r_passphrase = get_membuf (&data, NULL);
1215       if (!*r_passphrase)
1216         rc = gpg_error_from_syserror ();
1217     }
1218   return rc;
1219  no_mem:
1220   rc = gpg_error_from_syserror ();
1221   xfree (arg1);
1222   xfree (arg2);
1223   xfree (arg3);
1224   xfree (arg4);
1225   return rc;
1226 }
1227
1228
1229 gpg_error_t
1230 agent_clear_passphrase (const char *cache_id)
1231 {
1232   int rc;
1233   char line[ASSUAN_LINELENGTH];
1234
1235   if (!cache_id || !*cache_id)
1236     return 0;
1237
1238   rc = start_agent (0);
1239   if (rc)
1240     return rc;
1241
1242   snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
1243   line[DIM(line)-1] = 0;
1244   return assuan_transact (agent_ctx, line, NULL, NULL,
1245                           default_inq_cb, NULL, NULL, NULL);
1246 }
1247
1248
1249 /* Ask the agent to pop up a confirmation dialog with the text DESC
1250    and an okay and cancel button. */
1251 gpg_error_t
1252 gpg_agent_get_confirmation (const char *desc)
1253 {
1254   int rc;
1255   char *tmp;
1256   char line[ASSUAN_LINELENGTH];
1257
1258   rc = start_agent (0);
1259   if (rc)
1260     return rc;
1261
1262   tmp = percent_plus_escape (desc);
1263   if (!tmp)
1264     return gpg_error_from_syserror ();
1265   snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", tmp);
1266   line[DIM(line)-1] = 0;
1267   xfree (tmp);
1268
1269   rc = assuan_transact (agent_ctx, line, NULL, NULL,
1270                         default_inq_cb, NULL, NULL, NULL);
1271   return rc;
1272 }
1273
1274
1275 /* Return the S2K iteration count as computed by gpg-agent.  */
1276 gpg_error_t
1277 agent_get_s2k_count (unsigned long *r_count)
1278 {
1279   gpg_error_t err;
1280   membuf_t data;
1281   char *buf;
1282
1283   *r_count = 0;
1284
1285   err = start_agent (0);
1286   if (err)
1287     return err;
1288
1289   init_membuf (&data, 32);
1290   err = assuan_transact (agent_ctx, "GETINFO s2k_count", 
1291                         membuf_data_cb, &data,
1292                         NULL, NULL, NULL, NULL);
1293   if (err)
1294     xfree (get_membuf (&data, NULL));
1295   else 
1296     {
1297       put_membuf (&data, "", 1);
1298       buf = get_membuf (&data, NULL);
1299       if (!buf)
1300         err = gpg_error_from_syserror ();
1301       else
1302         {
1303           *r_count = strtoul (buf, NULL, 10);
1304           xfree (buf);
1305         }
1306     }
1307   return err;
1308 }
1309