64b5cd8574daa6baf36378ac5631dd7daba59d03
[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 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 #include <assuan.h>
33
34 #include "gpg.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 int 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 int
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
243 /* This is the default inquiry callback.  It mainly handles the
244    Pinentry notifications.  */
245 static int
246 default_inq_cb (void *opaque, const char *line)
247 {
248   (void)opaque;
249
250   if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
251     {
252       /* There is no working server mode yet thus we use
253          AllowSetForegroundWindow window right here.  We might want to
254          do this anyway in case gpg is called on the console. */
255       gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
256       /* We do not pass errors to avoid breaking other code.  */
257     }
258   else
259     log_debug ("ignoring gpg-agent inquiry `%s'\n", line);
260
261   return 0;
262 }
263
264
265
266 /* Release the card info structure INFO. */
267 void
268 agent_release_card_info (struct agent_card_info_s *info)
269 {
270   if (!info)
271     return;
272
273   xfree (info->serialno); info->serialno = NULL;
274   xfree (info->apptype); info->apptype = NULL;
275   xfree (info->disp_name); info->disp_name = NULL;
276   xfree (info->disp_lang); info->disp_lang = NULL;
277   xfree (info->pubkey_url); info->pubkey_url = NULL;
278   xfree (info->login_data); info->login_data = NULL;
279   info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
280   info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
281 }
282
283 static int
284 learn_status_cb (void *opaque, const char *line)
285 {
286   struct agent_card_info_s *parm = opaque;
287   const char *keyword = line;
288   int keywordlen;
289   int i;
290
291   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
292     ;
293   while (spacep (line))
294     line++;
295
296   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
297     {
298       xfree (parm->serialno);
299       parm->serialno = store_serialno (line);
300       parm->is_v2 = (strlen (parm->serialno) >= 16 
301                      && xtoi_2 (parm->serialno+12) >= 2 );
302     }
303   else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen))
304     {
305       xfree (parm->apptype);
306       parm->apptype = unescape_status_string (line);
307     }
308   else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
309     {
310       xfree (parm->disp_name);
311       parm->disp_name = unescape_status_string (line);
312     }
313   else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
314     {
315       xfree (parm->disp_lang);
316       parm->disp_lang = unescape_status_string (line);
317     }
318   else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
319     {
320       parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
321     }
322   else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
323     {
324       xfree (parm->pubkey_url);
325       parm->pubkey_url = unescape_status_string (line);
326     }
327   else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
328     {
329       xfree (parm->login_data);
330       parm->login_data = unescape_status_string (line);
331     }
332   else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
333     {
334       parm->sig_counter = strtoul (line, NULL, 0);
335     }
336   else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
337     {
338       char *p, *buf;
339
340       buf = p = unescape_status_string (line);
341       if (buf)
342         {
343           while (spacep (p))
344             p++;
345           parm->chv1_cached = atoi (p);
346           while (*p && !spacep (p))
347             p++;
348           while (spacep (p))
349             p++;
350           for (i=0; *p && i < 3; i++)
351             {
352               parm->chvmaxlen[i] = atoi (p);
353               while (*p && !spacep (p))
354                 p++;
355               while (spacep (p))
356                 p++;
357             }
358           for (i=0; *p && i < 3; i++)
359             {
360               parm->chvretry[i] = atoi (p);
361               while (*p && !spacep (p))
362                 p++;
363               while (spacep (p))
364                 p++;
365             }
366           xfree (buf);
367         }
368     }
369   else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen))
370     {
371       char *p, *p2, *buf;
372       int abool;
373
374       buf = p = unescape_status_string (line);
375       if (buf)
376         {
377           for (p = strtok (buf, " "); p; p = strtok (NULL, " "))
378             {
379               p2 = strchr (p, '=');
380               if (p2)
381                 {
382                   *p2++ = 0;
383                   abool = (*p2 == '1');
384                   if (!strcmp (p, "ki"))
385                     parm->extcap.ki = abool;
386                   else if (!strcmp (p, "aac"))
387                     parm->extcap.aac = abool;
388                 }
389             }
390           xfree (buf);
391         }
392     }
393   else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
394     {
395       int no = atoi (line);
396       while (*line && !spacep (line))
397         line++;
398       while (spacep (line))
399         line++;
400       if (no == 1)
401         parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
402       else if (no == 2)
403         parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
404       else if (no == 3)
405         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
406     }
407   else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
408     {
409       int no = atoi (line);
410       while (* line && !spacep (line))
411         line++;
412       while (spacep (line))
413         line++;
414       if (no == 1)
415         parm->fpr1time = strtoul (line, NULL, 10);
416       else if (no == 2)
417         parm->fpr2time = strtoul (line, NULL, 10);
418       else if (no == 3)
419         parm->fpr3time = strtoul (line, NULL, 10);
420     }
421   else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
422     {
423       int no = atoi (line);
424       while (*line && !spacep (line))
425         line++;
426       while (spacep (line))
427         line++;
428       if (no == 1)
429         parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
430       else if (no == 2)
431         parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
432       else if (no == 3)
433         parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
434     }
435   else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
436     {
437       int keyno, algo, nbits;
438
439       sscanf (line, "%d %d %d", &keyno, &algo, &nbits);
440       keyno--;
441       if (keyno >= 0 && keyno < DIM (parm->key_attr))
442         {
443           parm->key_attr[keyno].algo = algo;
444           parm->key_attr[keyno].nbits = nbits;
445         }
446     }
447
448   return 0;
449 }
450
451 /* Call the agent to learn about a smartcard */
452 int
453 agent_learn (struct agent_card_info_s *info)
454 {
455   int rc;
456
457   rc = start_agent (1);
458   if (rc)
459     return rc;
460
461   /* Send the serialno command to initialize the connection.  We don't
462      care about the data returned.  If the card has already been
463      initialized, this is a very fast command.  The main reason we
464      need to do this here is to handle a card removed case so that an
465      "l" command in --card-edit can be used to show ta newly inserted
466      card.  We request the openpgp card because that is what we
467      expect. */
468   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
469                         NULL, NULL, NULL, NULL, NULL, NULL);
470   if (rc)
471     return rc;
472
473
474   memset (info, 0, sizeof *info);
475   rc = assuan_transact (agent_ctx, "SCD LEARN --force",
476                         dummy_data_cb, NULL, default_inq_cb, NULL,
477                         learn_status_cb, info);
478   /* Also try to get the key attributes.  */
479   if (!rc)
480     agent_scd_getattr ("KEY-ATTR", info);
481   
482   return rc;
483 }
484
485 /* Call the agent to retrieve a data object.  This function returns
486    the data in the same structure as used by the learn command.  It is
487    allowed to update such a structure using this commmand. */
488 int
489 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
490 {
491   int rc;
492   char line[ASSUAN_LINELENGTH];
493
494   if (!*name)
495     return gpg_error (GPG_ERR_INV_VALUE);
496
497   /* We assume that NAME does not need escaping. */
498   if (12 + strlen (name) > DIM(line)-1)
499     return gpg_error (GPG_ERR_TOO_LARGE);
500   stpcpy (stpcpy (line, "SCD GETATTR "), name); 
501
502   rc = start_agent (1);
503   if (rc)
504     return rc;
505
506   rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
507                         learn_status_cb, info);
508   
509   return rc;
510 }
511
512 \f
513 /* Send an setattr command to the SCdaemon.  SERIALNO is not actually
514    used here but required by gpg 1.4's implementation of this code in
515    cardglue.c. */
516 int
517 agent_scd_setattr (const char *name,
518                    const unsigned char *value, size_t valuelen,
519                    const char *serialno)
520 {
521   int rc;
522   char line[ASSUAN_LINELENGTH];
523   char *p;
524
525   (void)serialno;
526
527   if (!*name || !valuelen)
528     return gpg_error (GPG_ERR_INV_VALUE);
529
530   /* We assume that NAME does not need escaping. */
531   if (12 + strlen (name) > DIM(line)-1)
532     return gpg_error (GPG_ERR_TOO_LARGE);
533       
534   p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
535   *p++ = ' ';
536   for (; valuelen; value++, valuelen--)
537     {
538       if (p >= line + DIM(line)-5 )
539         return gpg_error (GPG_ERR_TOO_LARGE);
540       if (*value < ' ' || *value == '+' || *value == '%')
541         {
542           sprintf (p, "%%%02X", *value);
543           p += 3;
544         }
545       else if (*value == ' ')
546         *p++ = '+';
547       else
548         *p++ = *value;
549     }
550   *p = 0;
551
552   rc = start_agent (1);
553   if (!rc)
554     {
555       rc = assuan_transact (agent_ctx, line, NULL, NULL, 
556                             default_inq_cb, NULL, NULL, NULL);
557     }
558
559   status_sc_op_failure (rc);
560   return rc;
561 }
562
563
564 \f
565 /* Handle a CERTDATA inquiry.  Note, we only send the data,
566    assuan_transact takes care of flushing and writing the END
567    command. */
568 static int
569 inq_writecert_parms (void *opaque, const char *line)
570 {
571   int rc;
572   struct writecert_parm_s *parm = opaque; 
573
574   if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
575     {
576       rc = assuan_send_data (parm->ctx, parm->certdata, parm->certdatalen);
577     }
578   else
579     rc = default_inq_cb (opaque, line);
580
581   return rc;
582 }
583
584
585 /* Send a WRITECERT command to the SCdaemon. */
586 int 
587 agent_scd_writecert (const char *certidstr,
588                      const unsigned char *certdata, size_t certdatalen)
589 {
590   int rc;
591   char line[ASSUAN_LINELENGTH];
592   struct writecert_parm_s parms;
593
594   rc = start_agent (1);
595   if (rc)
596     return rc;
597
598   memset (&parms, 0, sizeof parms);
599
600   snprintf (line, DIM(line)-1, "SCD WRITECERT %s", certidstr);
601   line[DIM(line)-1] = 0;
602   parms.ctx = agent_ctx;
603   parms.certdata = certdata;
604   parms.certdatalen = certdatalen;
605   
606   rc = assuan_transact (agent_ctx, line, NULL, NULL,
607                         inq_writecert_parms, &parms, NULL, NULL);
608
609   return rc;
610 }
611
612
613 \f
614 /* Handle a KEYDATA inquiry.  Note, we only send the data,
615    assuan_transact takes care of flushing and writing the end */
616 static int
617 inq_writekey_parms (void *opaque, const char *line)
618 {
619   int rc;
620   struct writekey_parm_s *parm = opaque; 
621
622   if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
623     {
624       rc = assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
625     }
626   else
627     rc = default_inq_cb (opaque, line);
628
629   return rc;
630 }
631
632
633 /* Send a WRITEKEY command to the SCdaemon. */
634 int 
635 agent_scd_writekey (int keyno, const char *serialno,
636                     const unsigned char *keydata, size_t keydatalen)
637 {
638   int rc;
639   char line[ASSUAN_LINELENGTH];
640   struct writekey_parm_s parms;
641
642   (void)serialno;
643
644   rc = start_agent (1);
645   if (rc)
646     return rc;
647
648   memset (&parms, 0, sizeof parms);
649
650   snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
651   line[DIM(line)-1] = 0;
652   parms.ctx = agent_ctx;
653   parms.keydata = keydata;
654   parms.keydatalen = keydatalen;
655   
656   rc = assuan_transact (agent_ctx, line, NULL, NULL,
657                         inq_writekey_parms, &parms, NULL, NULL);
658
659   status_sc_op_failure (rc);
660   return rc;
661 }
662
663
664 \f
665 /* Status callback for the SCD GENKEY command. */
666 static int
667 scd_genkey_cb (void *opaque, const char *line)
668 {
669   struct agent_card_genkey_s *parm = opaque;
670   const char *keyword = line;
671   int keywordlen;
672   gpg_error_t rc;
673
674   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
675     ;
676   while (spacep (line))
677     line++;
678
679   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
680     {
681       parm->fprvalid = unhexify_fpr (line, parm->fpr);
682     }
683   else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
684     {
685       gcry_mpi_t a;
686       const char *name = line;
687
688       while (*line && !spacep (line))
689         line++;
690       while (spacep (line))
691         line++;
692
693       rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
694       if (rc)
695         log_error ("error parsing received key data: %s\n", gpg_strerror (rc));
696       else if (*name == 'n' && spacep (name+1))
697         parm->n = a;
698       else if (*name == 'e' && spacep (name+1))
699         parm->e = a;
700       else
701         {
702           log_info ("unknown parameter name in received key data\n");
703           gcry_mpi_release (a);
704         }
705     }
706   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
707     {
708       parm->created_at = (u32)strtoul (line, NULL, 10);
709     }
710   else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
711     {
712       write_status_text (STATUS_PROGRESS, line);
713     }
714
715   return 0;
716 }
717
718 /* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
719    this implementation.  If CREATEDATE has been given, it will be
720    passed to SCDAEMON so that the key can be created with this
721    timestamp; note the user needs to use the returned timestamp as old
722    versions of scddaemon don't support this option.  */
723 int
724 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
725                   const char *serialno, u32 createtime)
726 {
727   int rc;
728   char line[ASSUAN_LINELENGTH];
729   gnupg_isotime_t tbuf;
730
731   (void)serialno;
732
733   rc = start_agent (1);
734   if (rc)
735     return rc;
736
737   if (createtime)
738     epoch2isotime (tbuf, createtime);
739   else
740     *tbuf = 0;
741
742   memset (info, 0, sizeof *info);
743   snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
744             *tbuf? "--timestamp=":"", tbuf,
745             force? "--force":"", 
746             keyno);
747   line[DIM(line)-1] = 0;
748
749   memset (info, 0, sizeof *info);
750   rc = assuan_transact (agent_ctx, line,
751                         NULL, NULL, default_inq_cb, NULL,
752                         scd_genkey_cb, info);
753   
754   status_sc_op_failure (rc);
755   return rc;
756 }
757
758 \f
759 static int
760 membuf_data_cb (void *opaque, const void *buffer, size_t length)
761 {
762   membuf_t *data = opaque;
763
764   if (buffer)
765     put_membuf (data, buffer, length);
766   return 0;
767 }
768   
769 /* Send a sign command to the scdaemon via gpg-agent's pass thru
770    mechanism. */
771 int
772 agent_scd_pksign (const char *serialno, int hashalgo,
773                   const unsigned char *indata, size_t indatalen,
774                   unsigned char **r_buf, size_t *r_buflen)
775 {
776   int rc, i;
777   char *p, line[ASSUAN_LINELENGTH];
778   membuf_t data;
779   size_t len;
780
781   /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
782
783   *r_buf = NULL;
784   *r_buflen = 0;
785
786   rc = start_agent (1);
787   if (rc)
788     return rc;
789
790   if (indatalen*2 + 50 > DIM(line))
791     return gpg_error (GPG_ERR_GENERAL);
792
793   /* Send the serialno command to initialize the connection. We don't
794      care about the data returned.  If the card has already been
795      initialized, this is a very fast command.  We request the openpgp
796      card because that is what we expect. */
797   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
798                         NULL, NULL, NULL, NULL, NULL, NULL);
799   if (rc)
800     return rc;
801
802   sprintf (line, "SCD SETDATA ");
803   p = line + strlen (line);
804   for (i=0; i < indatalen ; i++, p += 2 )
805     sprintf (p, "%02X", indata[i]);
806   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
807   if (rc)
808     return rc;
809
810   init_membuf (&data, 1024);
811 #if 0
812   if (!hashalgo) /* Temporary test hack. */
813     snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
814   else
815 #endif
816     snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s",
817               hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "",
818               serialno);
819   line[DIM(line)-1] = 0;
820   rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
821                         default_inq_cb, NULL, NULL, NULL);
822   if (rc)
823     {
824       xfree (get_membuf (&data, &len));
825     }
826   else
827     *r_buf = get_membuf (&data, r_buflen);
828
829   status_sc_op_failure (rc);
830   return rc;
831 }
832
833
834 /* Decrypt INDATA of length INDATALEN using the card identified by
835    SERIALNO.  Return the plaintext in a nwly allocated buffer stored
836    at the address of R_BUF. 
837
838    Note, we currently support only RSA or more exactly algorithms
839    taking one input data element. */
840 int
841 agent_scd_pkdecrypt (const char *serialno,
842                      const unsigned char *indata, size_t indatalen,
843                      unsigned char **r_buf, size_t *r_buflen)
844 {
845   int rc, i;
846   char *p, line[ASSUAN_LINELENGTH];
847   membuf_t data;
848   size_t len;
849
850   *r_buf = NULL;
851   rc = start_agent (1);
852   if (rc)
853     return rc;
854
855   /* FIXME: use secure memory where appropriate */
856   if (indatalen*2 + 50 > DIM(line))
857     return gpg_error (GPG_ERR_GENERAL);
858
859   /* Send the serialno command to initialize the connection. We don't
860      care about the data returned.  If the card has already been
861      initialized, this is a very fast command.  We request the openpgp
862      card because that is what we expect. */
863   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
864                         NULL, NULL, NULL, NULL, NULL, NULL);
865   if (rc)
866     return rc;
867
868   sprintf (line, "SCD SETDATA ");
869   p = line + strlen (line);
870   for (i=0; i < indatalen ; i++, p += 2 )
871     sprintf (p, "%02X", indata[i]);
872   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
873   if (rc)
874     return rc;
875
876   init_membuf (&data, 1024);
877   snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
878   line[DIM(line)-1] = 0;
879   rc = assuan_transact (agent_ctx, line,
880                         membuf_data_cb, &data,
881                         default_inq_cb, NULL, NULL, NULL);
882   if (rc)
883     {
884       xfree (get_membuf (&data, &len));
885     }
886   else
887     {
888       *r_buf = get_membuf (&data, r_buflen);
889       if (!*r_buf)
890         rc = gpg_error (GPG_ERR_ENOMEM);
891     }
892
893   status_sc_op_failure (rc);
894   return rc;
895 }
896
897
898 \f
899 /* Send a READCERT command to the SCdaemon. */
900 int 
901 agent_scd_readcert (const char *certidstr,
902                     void **r_buf, size_t *r_buflen)
903 {
904   int rc;
905   char line[ASSUAN_LINELENGTH];
906   membuf_t data;
907   size_t len;
908
909   *r_buf = NULL;
910   rc = start_agent (1);
911   if (rc)
912     return rc;
913
914   init_membuf (&data, 2048);
915
916   snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
917   line[DIM(line)-1] = 0;
918   rc = assuan_transact (agent_ctx, line,
919                         membuf_data_cb, &data,
920                         default_inq_cb, NULL, NULL, NULL);
921   if (rc)
922     {
923       xfree (get_membuf (&data, &len));
924       return rc;
925     }
926   *r_buf = get_membuf (&data, r_buflen);
927   if (!*r_buf)
928     return gpg_error (GPG_ERR_ENOMEM);
929
930   return 0;
931 }
932
933
934 \f
935 /* Change the PIN of an OpenPGP card or reset the retry counter.
936    CHVNO 1: Change the PIN
937          2: For v1 cards: Same as 1.
938             For v2 cards: Reset the PIN using the Reset Code.
939          3: Change the admin PIN
940        101: Set a new PIN and reset the retry counter
941        102: For v1 cars: Same as 101.
942             For v2 cards: Set a new Reset Code.
943    SERIALNO is not used.
944  */
945 int
946 agent_scd_change_pin (int chvno, const char *serialno)
947 {
948   int rc;
949   char line[ASSUAN_LINELENGTH];
950   const char *reset = "";
951
952   (void)serialno;
953
954   if (chvno >= 100)
955     reset = "--reset";
956   chvno %= 100;
957
958   rc = start_agent (1);
959   if (rc)
960     return rc;
961
962   snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
963   line[DIM(line)-1] = 0;
964   rc = assuan_transact (agent_ctx, line, NULL, NULL,
965                         default_inq_cb, NULL, NULL, NULL);
966   status_sc_op_failure (rc);
967   return rc;
968 }
969
970
971 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
972    number of the card - optionally followed by the fingerprint;
973    however the fingerprint is ignored here. */
974 int
975 agent_scd_checkpin  (const char *serialno)
976 {
977   int rc;
978   char line[ASSUAN_LINELENGTH];
979
980   rc = start_agent (1);
981   if (rc)
982     return rc;
983
984   snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
985   line[DIM(line)-1] = 0;
986   rc = assuan_transact (agent_ctx, line,
987                         NULL, NULL,
988                         default_inq_cb, NULL, NULL, NULL);
989   status_sc_op_failure (rc);
990   return rc;
991 }
992
993
994 /* Dummy function, only used by the gpg 1.4 implementation. */
995 void
996 agent_clear_pin_cache (const char *sn)
997 {
998   (void)sn;
999 }
1000
1001
1002
1003 \f
1004 /* Note: All strings shall be UTF-8. On success the caller needs to
1005    free the string stored at R_PASSPHRASE. On error NULL will be
1006    stored at R_PASSPHRASE and an appropriate fpf error code
1007    returned. */
1008 gpg_error_t
1009 agent_get_passphrase (const char *cache_id,
1010                       const char *err_msg,
1011                       const char *prompt,
1012                       const char *desc_msg,
1013                       int repeat,
1014                       int check,
1015                       char **r_passphrase)
1016 {
1017   int rc;
1018   char line[ASSUAN_LINELENGTH];
1019   char *arg1 = NULL;
1020   char *arg2 = NULL;  
1021   char *arg3 = NULL; 
1022   char *arg4 = NULL;
1023   membuf_t data;
1024
1025   *r_passphrase = NULL;
1026
1027   rc = start_agent (0);
1028   if (rc)
1029     return rc;
1030
1031   /* Check that the gpg-agent understands the repeat option.  */
1032   if (assuan_transact (agent_ctx, 
1033                        "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1034                        NULL, NULL, NULL, NULL, NULL, NULL))
1035     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1036
1037   if (cache_id && *cache_id)
1038     if (!(arg1 = percent_plus_escape (cache_id)))
1039       goto no_mem;
1040   if (err_msg && *err_msg)
1041     if (!(arg2 = percent_plus_escape (err_msg)))
1042       goto no_mem;
1043   if (prompt && *prompt)
1044     if (!(arg3 = percent_plus_escape (prompt)))
1045       goto no_mem;
1046   if (desc_msg && *desc_msg)
1047     if (!(arg4 = percent_plus_escape (desc_msg)))
1048       goto no_mem;
1049
1050   snprintf (line, DIM(line)-1, 
1051             "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", 
1052             repeat, 
1053             check? " --check --qualitybar":"",
1054             arg1? arg1:"X",
1055             arg2? arg2:"X",
1056             arg3? arg3:"X",
1057             arg4? arg4:"X");
1058   line[DIM(line)-1] = 0;
1059   xfree (arg1);
1060   xfree (arg2);
1061   xfree (arg3);
1062   xfree (arg4);
1063
1064   init_membuf_secure (&data, 64);
1065   rc = assuan_transact (agent_ctx, line, 
1066                         membuf_data_cb, &data,
1067                         default_inq_cb, NULL, NULL, NULL);
1068
1069   if (rc)
1070     xfree (get_membuf (&data, NULL));
1071   else 
1072     {
1073       put_membuf (&data, "", 1);
1074       *r_passphrase = get_membuf (&data, NULL);
1075       if (!*r_passphrase)
1076         rc = gpg_error_from_syserror ();
1077     }
1078   return rc;
1079  no_mem:
1080   rc = gpg_error_from_syserror ();
1081   xfree (arg1);
1082   xfree (arg2);
1083   xfree (arg3);
1084   xfree (arg4);
1085   return rc;
1086 }
1087
1088
1089 gpg_error_t
1090 agent_clear_passphrase (const char *cache_id)
1091 {
1092   int rc;
1093   char line[ASSUAN_LINELENGTH];
1094
1095   if (!cache_id || !*cache_id)
1096     return 0;
1097
1098   rc = start_agent (0);
1099   if (rc)
1100     return rc;
1101
1102   snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
1103   line[DIM(line)-1] = 0;
1104   return assuan_transact (agent_ctx, line, NULL, NULL,
1105                           default_inq_cb, NULL, NULL, NULL);
1106 }