Comment changes.
[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   memset (info, 0, sizeof *info);
462   rc = assuan_transact (agent_ctx, "SCD LEARN --force",
463                         dummy_data_cb, NULL, default_inq_cb, NULL,
464                         learn_status_cb, info);
465   /* Also try to get the key attributes.  */
466   if (!rc)
467     agent_scd_getattr ("KEY-ATTR", info);
468   
469   return rc;
470 }
471
472 /* Call the agent to retrieve a data object.  This function returns
473    the data in the same structure as used by the learn command.  It is
474    allowed to update such a structure using this commmand. */
475 int
476 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
477 {
478   int rc;
479   char line[ASSUAN_LINELENGTH];
480
481   if (!*name)
482     return gpg_error (GPG_ERR_INV_VALUE);
483
484   /* We assume that NAME does not need escaping. */
485   if (12 + strlen (name) > DIM(line)-1)
486     return gpg_error (GPG_ERR_TOO_LARGE);
487   stpcpy (stpcpy (line, "SCD GETATTR "), name); 
488
489   rc = start_agent (1);
490   if (rc)
491     return rc;
492
493   rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
494                         learn_status_cb, info);
495   
496   return rc;
497 }
498
499 \f
500 /* Send an setattr command to the SCdaemon.  SERIALNO is not actually
501    used here but required by gpg 1.4's implementation of this code in
502    cardglue.c. */
503 int
504 agent_scd_setattr (const char *name,
505                    const unsigned char *value, size_t valuelen,
506                    const char *serialno)
507 {
508   int rc;
509   char line[ASSUAN_LINELENGTH];
510   char *p;
511
512   (void)serialno;
513
514   if (!*name || !valuelen)
515     return gpg_error (GPG_ERR_INV_VALUE);
516
517   /* We assume that NAME does not need escaping. */
518   if (12 + strlen (name) > DIM(line)-1)
519     return gpg_error (GPG_ERR_TOO_LARGE);
520       
521   p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
522   *p++ = ' ';
523   for (; valuelen; value++, valuelen--)
524     {
525       if (p >= line + DIM(line)-5 )
526         return gpg_error (GPG_ERR_TOO_LARGE);
527       if (*value < ' ' || *value == '+' || *value == '%')
528         {
529           sprintf (p, "%%%02X", *value);
530           p += 3;
531         }
532       else if (*value == ' ')
533         *p++ = '+';
534       else
535         *p++ = *value;
536     }
537   *p = 0;
538
539   rc = start_agent (1);
540   if (!rc)
541     {
542       rc = assuan_transact (agent_ctx, line, NULL, NULL, 
543                             default_inq_cb, NULL, NULL, NULL);
544     }
545
546   status_sc_op_failure (rc);
547   return rc;
548 }
549
550
551 \f
552 /* Handle a CERTDATA inquiry.  Note, we only send the data,
553    assuan_transact takes care of flushing and writing the END
554    command. */
555 static int
556 inq_writecert_parms (void *opaque, const char *line)
557 {
558   int rc;
559   struct writecert_parm_s *parm = opaque; 
560
561   if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
562     {
563       rc = assuan_send_data (parm->ctx, parm->certdata, parm->certdatalen);
564     }
565   else
566     rc = default_inq_cb (opaque, line);
567
568   return rc;
569 }
570
571
572 /* Send a WRITECERT command to the SCdaemon. */
573 int 
574 agent_scd_writecert (const char *certidstr,
575                      const unsigned char *certdata, size_t certdatalen)
576 {
577   int rc;
578   char line[ASSUAN_LINELENGTH];
579   struct writecert_parm_s parms;
580
581   rc = start_agent (1);
582   if (rc)
583     return rc;
584
585   memset (&parms, 0, sizeof parms);
586
587   snprintf (line, DIM(line)-1, "SCD WRITECERT %s", certidstr);
588   line[DIM(line)-1] = 0;
589   parms.ctx = agent_ctx;
590   parms.certdata = certdata;
591   parms.certdatalen = certdatalen;
592   
593   rc = assuan_transact (agent_ctx, line, NULL, NULL,
594                         inq_writecert_parms, &parms, NULL, NULL);
595
596   return rc;
597 }
598
599
600 \f
601 /* Handle a KEYDATA inquiry.  Note, we only send the data,
602    assuan_transact takes care of flushing and writing the end */
603 static int
604 inq_writekey_parms (void *opaque, const char *line)
605 {
606   int rc;
607   struct writekey_parm_s *parm = opaque; 
608
609   if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
610     {
611       rc = assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
612     }
613   else
614     rc = default_inq_cb (opaque, line);
615
616   return rc;
617 }
618
619
620 /* Send a WRITEKEY command to the SCdaemon. */
621 int 
622 agent_scd_writekey (int keyno, const char *serialno,
623                     const unsigned char *keydata, size_t keydatalen)
624 {
625   int rc;
626   char line[ASSUAN_LINELENGTH];
627   struct writekey_parm_s parms;
628
629   (void)serialno;
630
631   rc = start_agent (1);
632   if (rc)
633     return rc;
634
635   memset (&parms, 0, sizeof parms);
636
637   snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
638   line[DIM(line)-1] = 0;
639   parms.ctx = agent_ctx;
640   parms.keydata = keydata;
641   parms.keydatalen = keydatalen;
642   
643   rc = assuan_transact (agent_ctx, line, NULL, NULL,
644                         inq_writekey_parms, &parms, NULL, NULL);
645
646   status_sc_op_failure (rc);
647   return rc;
648 }
649
650
651 \f
652 /* Status callback for the SCD GENKEY command. */
653 static int
654 scd_genkey_cb (void *opaque, const char *line)
655 {
656   struct agent_card_genkey_s *parm = opaque;
657   const char *keyword = line;
658   int keywordlen;
659   gpg_error_t rc;
660
661   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
662     ;
663   while (spacep (line))
664     line++;
665
666   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
667     {
668       parm->fprvalid = unhexify_fpr (line, parm->fpr);
669     }
670   if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
671     {
672       gcry_mpi_t a;
673       const char *name = line;
674
675       while (*line && !spacep (line))
676         line++;
677       while (spacep (line))
678         line++;
679
680       rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
681       if (rc)
682         log_error ("error parsing received key data: %s\n", gpg_strerror (rc));
683       else if (*name == 'n' && spacep (name+1))
684         parm->n = a;
685       else if (*name == 'e' && spacep (name+1))
686         parm->e = a;
687       else
688         {
689           log_info ("unknown parameter name in received key data\n");
690           gcry_mpi_release (a);
691         }
692     }
693   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
694     {
695       parm->created_at = (u32)strtoul (line, NULL, 10);
696     }
697
698   return 0;
699 }
700
701 /* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
702    this implementation.  If CREATEDATE has been given, it will be
703    passed to SCDAEMON so that the key can be created with this
704    timestamp; note the user needs to use the returned timestamp as old
705    versions of scddaemon don't support this option.  */
706 int
707 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
708                   const char *serialno, u32 createtime)
709 {
710   int rc;
711   char line[ASSUAN_LINELENGTH];
712   gnupg_isotime_t tbuf;
713
714   (void)serialno;
715
716   rc = start_agent (1);
717   if (rc)
718     return rc;
719
720   if (createtime)
721     epoch2isotime (tbuf, createtime);
722   else
723     *tbuf = 0;
724
725   memset (info, 0, sizeof *info);
726   snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
727             *tbuf? "--timestamp=":"", tbuf,
728             force? "--force":"", 
729             keyno);
730   line[DIM(line)-1] = 0;
731
732   memset (info, 0, sizeof *info);
733   rc = assuan_transact (agent_ctx, line,
734                         NULL, NULL, default_inq_cb, NULL,
735                         scd_genkey_cb, info);
736   
737   status_sc_op_failure (rc);
738   return rc;
739 }
740
741 \f
742 static int
743 membuf_data_cb (void *opaque, const void *buffer, size_t length)
744 {
745   membuf_t *data = opaque;
746
747   if (buffer)
748     put_membuf (data, buffer, length);
749   return 0;
750 }
751   
752 /* Send a sign command to the scdaemon via gpg-agent's pass thru
753    mechanism. */
754 int
755 agent_scd_pksign (const char *serialno, int hashalgo,
756                   const unsigned char *indata, size_t indatalen,
757                   unsigned char **r_buf, size_t *r_buflen)
758 {
759   int rc, i;
760   char *p, line[ASSUAN_LINELENGTH];
761   membuf_t data;
762   size_t len;
763
764   /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
765
766   *r_buf = NULL;
767   *r_buflen = 0;
768
769   rc = start_agent (1);
770   if (rc)
771     return rc;
772
773   if (indatalen*2 + 50 > DIM(line))
774     return gpg_error (GPG_ERR_GENERAL);
775
776   /* Send the serialno command to initialize the connection. We don't
777      care about the data returned.  If the card has already been
778      initialized, this is a very fast command.  We request the openpgp
779      card because that is what we expect. */
780   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
781                         NULL, NULL, NULL, NULL, NULL, NULL);
782   if (rc)
783     return rc;
784
785   sprintf (line, "SCD SETDATA ");
786   p = line + strlen (line);
787   for (i=0; i < indatalen ; i++, p += 2 )
788     sprintf (p, "%02X", indata[i]);
789   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
790   if (rc)
791     return rc;
792
793   init_membuf (&data, 1024);
794 #if 0
795   if (!hashalgo) /* Temporary test hack. */
796     snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
797   else
798 #endif
799     snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s",
800               hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "",
801               serialno);
802   line[DIM(line)-1] = 0;
803   rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
804                         default_inq_cb, NULL, NULL, NULL);
805   if (rc)
806     {
807       xfree (get_membuf (&data, &len));
808     }
809   else
810     *r_buf = get_membuf (&data, r_buflen);
811
812   status_sc_op_failure (rc);
813   return rc;
814 }
815
816
817 /* Decrypt INDATA of length INDATALEN using the card identified by
818    SERIALNO.  Return the plaintext in a nwly allocated buffer stored
819    at the address of R_BUF. 
820
821    Note, we currently support only RSA or more exactly algorithms
822    taking one input data element. */
823 int
824 agent_scd_pkdecrypt (const char *serialno,
825                      const unsigned char *indata, size_t indatalen,
826                      unsigned char **r_buf, size_t *r_buflen)
827 {
828   int rc, i;
829   char *p, line[ASSUAN_LINELENGTH];
830   membuf_t data;
831   size_t len;
832
833   *r_buf = NULL;
834   rc = start_agent (1);
835   if (rc)
836     return rc;
837
838   /* FIXME: use secure memory where appropriate */
839   if (indatalen*2 + 50 > DIM(line))
840     return gpg_error (GPG_ERR_GENERAL);
841
842   /* Send the serialno command to initialize the connection. We don't
843      care about the data returned.  If the card has already been
844      initialized, this is a very fast command.  We request the openpgp
845      card because that is what we expect. */
846   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
847                         NULL, NULL, NULL, NULL, NULL, NULL);
848   if (rc)
849     return rc;
850
851   sprintf (line, "SCD SETDATA ");
852   p = line + strlen (line);
853   for (i=0; i < indatalen ; i++, p += 2 )
854     sprintf (p, "%02X", indata[i]);
855   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
856   if (rc)
857     return rc;
858
859   init_membuf (&data, 1024);
860   snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
861   line[DIM(line)-1] = 0;
862   rc = assuan_transact (agent_ctx, line,
863                         membuf_data_cb, &data,
864                         default_inq_cb, NULL, NULL, NULL);
865   if (rc)
866     {
867       xfree (get_membuf (&data, &len));
868     }
869   else
870     {
871       *r_buf = get_membuf (&data, r_buflen);
872       if (!*r_buf)
873         rc = gpg_error (GPG_ERR_ENOMEM);
874     }
875
876   status_sc_op_failure (rc);
877   return rc;
878 }
879
880
881 \f
882 /* Send a READCERT command to the SCdaemon. */
883 int 
884 agent_scd_readcert (const char *certidstr,
885                     void **r_buf, size_t *r_buflen)
886 {
887   int rc;
888   char line[ASSUAN_LINELENGTH];
889   membuf_t data;
890   size_t len;
891
892   *r_buf = NULL;
893   rc = start_agent (1);
894   if (rc)
895     return rc;
896
897   init_membuf (&data, 2048);
898
899   snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
900   line[DIM(line)-1] = 0;
901   rc = assuan_transact (agent_ctx, line,
902                         membuf_data_cb, &data,
903                         default_inq_cb, NULL, NULL, NULL);
904   if (rc)
905     {
906       xfree (get_membuf (&data, &len));
907       return rc;
908     }
909   *r_buf = get_membuf (&data, r_buflen);
910   if (!*r_buf)
911     return gpg_error (GPG_ERR_ENOMEM);
912
913   return 0;
914 }
915
916
917 \f
918 /* Change the PIN of an OpenPGP card or reset the retry counter.
919    CHVNO 1: Change the PIN
920          2: For v1 cards: Same as 1.
921             For v2 cards: Reset the PIN using the Reset Code.
922          3: Change the admin PIN
923        101: Set a new PIN and reset the retry counter
924        102: For v1 cars: Same as 101.
925             For v2 cards: Set a new Reset Code.
926    SERIALNO is not used.
927  */
928 int
929 agent_scd_change_pin (int chvno, const char *serialno)
930 {
931   int rc;
932   char line[ASSUAN_LINELENGTH];
933   const char *reset = "";
934
935   (void)serialno;
936
937   if (chvno >= 100)
938     reset = "--reset";
939   chvno %= 100;
940
941   rc = start_agent (1);
942   if (rc)
943     return rc;
944
945   snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
946   line[DIM(line)-1] = 0;
947   rc = assuan_transact (agent_ctx, line, NULL, NULL,
948                         default_inq_cb, NULL, NULL, NULL);
949   status_sc_op_failure (rc);
950   return rc;
951 }
952
953
954 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
955    number of the card - optionally followed by the fingerprint;
956    however the fingerprint is ignored here. */
957 int
958 agent_scd_checkpin  (const char *serialno)
959 {
960   int rc;
961   char line[ASSUAN_LINELENGTH];
962
963   rc = start_agent (1);
964   if (rc)
965     return rc;
966
967   snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
968   line[DIM(line)-1] = 0;
969   rc = assuan_transact (agent_ctx, line,
970                         NULL, NULL,
971                         default_inq_cb, NULL, NULL, NULL);
972   status_sc_op_failure (rc);
973   return rc;
974 }
975
976
977 /* Dummy function, only used by the gpg 1.4 implementation. */
978 void
979 agent_clear_pin_cache (const char *sn)
980 {
981   (void)sn;
982 }
983
984
985
986 \f
987 /* Note: All strings shall be UTF-8. On success the caller needs to
988    free the string stored at R_PASSPHRASE. On error NULL will be
989    stored at R_PASSPHRASE and an appropriate fpf error code
990    returned. */
991 gpg_error_t
992 agent_get_passphrase (const char *cache_id,
993                       const char *err_msg,
994                       const char *prompt,
995                       const char *desc_msg,
996                       int repeat,
997                       int check,
998                       char **r_passphrase)
999 {
1000   int rc;
1001   char line[ASSUAN_LINELENGTH];
1002   char *arg1 = NULL;
1003   char *arg2 = NULL;  
1004   char *arg3 = NULL; 
1005   char *arg4 = NULL;
1006   membuf_t data;
1007
1008   *r_passphrase = NULL;
1009
1010   rc = start_agent (0);
1011   if (rc)
1012     return rc;
1013
1014   /* Check that the gpg-agent understands the repeat option.  */
1015   if (assuan_transact (agent_ctx, 
1016                        "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1017                        NULL, NULL, NULL, NULL, NULL, NULL))
1018     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1019
1020   if (cache_id && *cache_id)
1021     if (!(arg1 = percent_plus_escape (cache_id)))
1022       goto no_mem;
1023   if (err_msg && *err_msg)
1024     if (!(arg2 = percent_plus_escape (err_msg)))
1025       goto no_mem;
1026   if (prompt && *prompt)
1027     if (!(arg3 = percent_plus_escape (prompt)))
1028       goto no_mem;
1029   if (desc_msg && *desc_msg)
1030     if (!(arg4 = percent_plus_escape (desc_msg)))
1031       goto no_mem;
1032
1033   snprintf (line, DIM(line)-1, 
1034             "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", 
1035             repeat, 
1036             check? " --check --qualitybar":"",
1037             arg1? arg1:"X",
1038             arg2? arg2:"X",
1039             arg3? arg3:"X",
1040             arg4? arg4:"X");
1041   line[DIM(line)-1] = 0;
1042   xfree (arg1);
1043   xfree (arg2);
1044   xfree (arg3);
1045   xfree (arg4);
1046
1047   init_membuf_secure (&data, 64);
1048   rc = assuan_transact (agent_ctx, line, 
1049                         membuf_data_cb, &data,
1050                         default_inq_cb, NULL, NULL, NULL);
1051
1052   if (rc)
1053     xfree (get_membuf (&data, NULL));
1054   else 
1055     {
1056       put_membuf (&data, "", 1);
1057       *r_passphrase = get_membuf (&data, NULL);
1058       if (!*r_passphrase)
1059         rc = gpg_error_from_syserror ();
1060     }
1061   return rc;
1062  no_mem:
1063   rc = gpg_error_from_syserror ();
1064   xfree (arg1);
1065   xfree (arg2);
1066   xfree (arg3);
1067   xfree (arg4);
1068   return rc;
1069 }
1070
1071
1072 gpg_error_t
1073 agent_clear_passphrase (const char *cache_id)
1074 {
1075   int rc;
1076   char line[ASSUAN_LINELENGTH];
1077
1078   if (!cache_id || !*cache_id)
1079     return 0;
1080
1081   rc = start_agent (0);
1082   if (rc)
1083     return rc;
1084
1085   snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
1086   line[DIM(line)-1] = 0;
1087   return assuan_transact (agent_ctx, line, NULL, NULL,
1088                           default_inq_cb, NULL, NULL, NULL);
1089 }