Ask for the keysize when generating a new card key.
[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   else 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   else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
698     {
699       write_status_text (STATUS_PROGRESS, line);
700     }
701
702   return 0;
703 }
704
705 /* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
706    this implementation.  If CREATEDATE has been given, it will be
707    passed to SCDAEMON so that the key can be created with this
708    timestamp; note the user needs to use the returned timestamp as old
709    versions of scddaemon don't support this option.  */
710 int
711 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
712                   const char *serialno, u32 createtime)
713 {
714   int rc;
715   char line[ASSUAN_LINELENGTH];
716   gnupg_isotime_t tbuf;
717
718   (void)serialno;
719
720   rc = start_agent (1);
721   if (rc)
722     return rc;
723
724   if (createtime)
725     epoch2isotime (tbuf, createtime);
726   else
727     *tbuf = 0;
728
729   memset (info, 0, sizeof *info);
730   snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
731             *tbuf? "--timestamp=":"", tbuf,
732             force? "--force":"", 
733             keyno);
734   line[DIM(line)-1] = 0;
735
736   memset (info, 0, sizeof *info);
737   rc = assuan_transact (agent_ctx, line,
738                         NULL, NULL, default_inq_cb, NULL,
739                         scd_genkey_cb, info);
740   
741   status_sc_op_failure (rc);
742   return rc;
743 }
744
745 \f
746 static int
747 membuf_data_cb (void *opaque, const void *buffer, size_t length)
748 {
749   membuf_t *data = opaque;
750
751   if (buffer)
752     put_membuf (data, buffer, length);
753   return 0;
754 }
755   
756 /* Send a sign command to the scdaemon via gpg-agent's pass thru
757    mechanism. */
758 int
759 agent_scd_pksign (const char *serialno, int hashalgo,
760                   const unsigned char *indata, size_t indatalen,
761                   unsigned char **r_buf, size_t *r_buflen)
762 {
763   int rc, i;
764   char *p, line[ASSUAN_LINELENGTH];
765   membuf_t data;
766   size_t len;
767
768   /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
769
770   *r_buf = NULL;
771   *r_buflen = 0;
772
773   rc = start_agent (1);
774   if (rc)
775     return rc;
776
777   if (indatalen*2 + 50 > DIM(line))
778     return gpg_error (GPG_ERR_GENERAL);
779
780   /* Send the serialno command to initialize the connection. We don't
781      care about the data returned.  If the card has already been
782      initialized, this is a very fast command.  We request the openpgp
783      card because that is what we expect. */
784   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
785                         NULL, NULL, NULL, NULL, NULL, NULL);
786   if (rc)
787     return rc;
788
789   sprintf (line, "SCD SETDATA ");
790   p = line + strlen (line);
791   for (i=0; i < indatalen ; i++, p += 2 )
792     sprintf (p, "%02X", indata[i]);
793   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
794   if (rc)
795     return rc;
796
797   init_membuf (&data, 1024);
798 #if 0
799   if (!hashalgo) /* Temporary test hack. */
800     snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
801   else
802 #endif
803     snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s",
804               hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "",
805               serialno);
806   line[DIM(line)-1] = 0;
807   rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
808                         default_inq_cb, NULL, NULL, NULL);
809   if (rc)
810     {
811       xfree (get_membuf (&data, &len));
812     }
813   else
814     *r_buf = get_membuf (&data, r_buflen);
815
816   status_sc_op_failure (rc);
817   return rc;
818 }
819
820
821 /* Decrypt INDATA of length INDATALEN using the card identified by
822    SERIALNO.  Return the plaintext in a nwly allocated buffer stored
823    at the address of R_BUF. 
824
825    Note, we currently support only RSA or more exactly algorithms
826    taking one input data element. */
827 int
828 agent_scd_pkdecrypt (const char *serialno,
829                      const unsigned char *indata, size_t indatalen,
830                      unsigned char **r_buf, size_t *r_buflen)
831 {
832   int rc, i;
833   char *p, line[ASSUAN_LINELENGTH];
834   membuf_t data;
835   size_t len;
836
837   *r_buf = NULL;
838   rc = start_agent (1);
839   if (rc)
840     return rc;
841
842   /* FIXME: use secure memory where appropriate */
843   if (indatalen*2 + 50 > DIM(line))
844     return gpg_error (GPG_ERR_GENERAL);
845
846   /* Send the serialno command to initialize the connection. We don't
847      care about the data returned.  If the card has already been
848      initialized, this is a very fast command.  We request the openpgp
849      card because that is what we expect. */
850   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
851                         NULL, NULL, NULL, NULL, NULL, NULL);
852   if (rc)
853     return rc;
854
855   sprintf (line, "SCD SETDATA ");
856   p = line + strlen (line);
857   for (i=0; i < indatalen ; i++, p += 2 )
858     sprintf (p, "%02X", indata[i]);
859   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
860   if (rc)
861     return rc;
862
863   init_membuf (&data, 1024);
864   snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
865   line[DIM(line)-1] = 0;
866   rc = assuan_transact (agent_ctx, line,
867                         membuf_data_cb, &data,
868                         default_inq_cb, NULL, NULL, NULL);
869   if (rc)
870     {
871       xfree (get_membuf (&data, &len));
872     }
873   else
874     {
875       *r_buf = get_membuf (&data, r_buflen);
876       if (!*r_buf)
877         rc = gpg_error (GPG_ERR_ENOMEM);
878     }
879
880   status_sc_op_failure (rc);
881   return rc;
882 }
883
884
885 \f
886 /* Send a READCERT command to the SCdaemon. */
887 int 
888 agent_scd_readcert (const char *certidstr,
889                     void **r_buf, size_t *r_buflen)
890 {
891   int rc;
892   char line[ASSUAN_LINELENGTH];
893   membuf_t data;
894   size_t len;
895
896   *r_buf = NULL;
897   rc = start_agent (1);
898   if (rc)
899     return rc;
900
901   init_membuf (&data, 2048);
902
903   snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
904   line[DIM(line)-1] = 0;
905   rc = assuan_transact (agent_ctx, line,
906                         membuf_data_cb, &data,
907                         default_inq_cb, NULL, NULL, NULL);
908   if (rc)
909     {
910       xfree (get_membuf (&data, &len));
911       return rc;
912     }
913   *r_buf = get_membuf (&data, r_buflen);
914   if (!*r_buf)
915     return gpg_error (GPG_ERR_ENOMEM);
916
917   return 0;
918 }
919
920
921 \f
922 /* Change the PIN of an OpenPGP card or reset the retry counter.
923    CHVNO 1: Change the PIN
924          2: For v1 cards: Same as 1.
925             For v2 cards: Reset the PIN using the Reset Code.
926          3: Change the admin PIN
927        101: Set a new PIN and reset the retry counter
928        102: For v1 cars: Same as 101.
929             For v2 cards: Set a new Reset Code.
930    SERIALNO is not used.
931  */
932 int
933 agent_scd_change_pin (int chvno, const char *serialno)
934 {
935   int rc;
936   char line[ASSUAN_LINELENGTH];
937   const char *reset = "";
938
939   (void)serialno;
940
941   if (chvno >= 100)
942     reset = "--reset";
943   chvno %= 100;
944
945   rc = start_agent (1);
946   if (rc)
947     return rc;
948
949   snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
950   line[DIM(line)-1] = 0;
951   rc = assuan_transact (agent_ctx, line, NULL, NULL,
952                         default_inq_cb, NULL, NULL, NULL);
953   status_sc_op_failure (rc);
954   return rc;
955 }
956
957
958 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
959    number of the card - optionally followed by the fingerprint;
960    however the fingerprint is ignored here. */
961 int
962 agent_scd_checkpin  (const char *serialno)
963 {
964   int rc;
965   char line[ASSUAN_LINELENGTH];
966
967   rc = start_agent (1);
968   if (rc)
969     return rc;
970
971   snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
972   line[DIM(line)-1] = 0;
973   rc = assuan_transact (agent_ctx, line,
974                         NULL, NULL,
975                         default_inq_cb, NULL, NULL, NULL);
976   status_sc_op_failure (rc);
977   return rc;
978 }
979
980
981 /* Dummy function, only used by the gpg 1.4 implementation. */
982 void
983 agent_clear_pin_cache (const char *sn)
984 {
985   (void)sn;
986 }
987
988
989
990 \f
991 /* Note: All strings shall be UTF-8. On success the caller needs to
992    free the string stored at R_PASSPHRASE. On error NULL will be
993    stored at R_PASSPHRASE and an appropriate fpf error code
994    returned. */
995 gpg_error_t
996 agent_get_passphrase (const char *cache_id,
997                       const char *err_msg,
998                       const char *prompt,
999                       const char *desc_msg,
1000                       int repeat,
1001                       int check,
1002                       char **r_passphrase)
1003 {
1004   int rc;
1005   char line[ASSUAN_LINELENGTH];
1006   char *arg1 = NULL;
1007   char *arg2 = NULL;  
1008   char *arg3 = NULL; 
1009   char *arg4 = NULL;
1010   membuf_t data;
1011
1012   *r_passphrase = NULL;
1013
1014   rc = start_agent (0);
1015   if (rc)
1016     return rc;
1017
1018   /* Check that the gpg-agent understands the repeat option.  */
1019   if (assuan_transact (agent_ctx, 
1020                        "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1021                        NULL, NULL, NULL, NULL, NULL, NULL))
1022     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1023
1024   if (cache_id && *cache_id)
1025     if (!(arg1 = percent_plus_escape (cache_id)))
1026       goto no_mem;
1027   if (err_msg && *err_msg)
1028     if (!(arg2 = percent_plus_escape (err_msg)))
1029       goto no_mem;
1030   if (prompt && *prompt)
1031     if (!(arg3 = percent_plus_escape (prompt)))
1032       goto no_mem;
1033   if (desc_msg && *desc_msg)
1034     if (!(arg4 = percent_plus_escape (desc_msg)))
1035       goto no_mem;
1036
1037   snprintf (line, DIM(line)-1, 
1038             "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", 
1039             repeat, 
1040             check? " --check --qualitybar":"",
1041             arg1? arg1:"X",
1042             arg2? arg2:"X",
1043             arg3? arg3:"X",
1044             arg4? arg4:"X");
1045   line[DIM(line)-1] = 0;
1046   xfree (arg1);
1047   xfree (arg2);
1048   xfree (arg3);
1049   xfree (arg4);
1050
1051   init_membuf_secure (&data, 64);
1052   rc = assuan_transact (agent_ctx, line, 
1053                         membuf_data_cb, &data,
1054                         default_inq_cb, NULL, NULL, NULL);
1055
1056   if (rc)
1057     xfree (get_membuf (&data, NULL));
1058   else 
1059     {
1060       put_membuf (&data, "", 1);
1061       *r_passphrase = get_membuf (&data, NULL);
1062       if (!*r_passphrase)
1063         rc = gpg_error_from_syserror ();
1064     }
1065   return rc;
1066  no_mem:
1067   rc = gpg_error_from_syserror ();
1068   xfree (arg1);
1069   xfree (arg2);
1070   xfree (arg3);
1071   xfree (arg4);
1072   return rc;
1073 }
1074
1075
1076 gpg_error_t
1077 agent_clear_passphrase (const char *cache_id)
1078 {
1079   int rc;
1080   char line[ASSUAN_LINELENGTH];
1081
1082   if (!cache_id || !*cache_id)
1083     return 0;
1084
1085   rc = start_agent (0);
1086   if (rc)
1087     return rc;
1088
1089   snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
1090   line[DIM(line)-1] = 0;
1091   return assuan_transact (agent_ctx, line, NULL, NULL,
1092                           default_inq_cb, NULL, NULL, NULL);
1093 }