Even less prompts for a new key now.
[gnupg.git] / g10 / call-agent.c
1 /* call-agent.c - Divert GPG operations to the agent.
2  * Copyright (C) 2001, 2002, 2003, 2006, 2007, 2008, 2009,
3  *               2010 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h> 
27 #include <time.h>
28 #include <assert.h>
29 #ifdef HAVE_LOCALE_H
30 #include <locale.h>
31 #endif
32
33 #include "gpg.h"
34 #include <assuan.h>
35 #include "util.h"
36 #include "membuf.h"
37 #include "options.h"
38 #include "i18n.h"
39 #include "asshelp.h"
40 #include "sysutils.h"
41 #include "call-agent.h"
42 #include "status.h"
43
44 #ifndef DBG_ASSUAN
45 # define DBG_ASSUAN 1
46 #endif
47
48 static assuan_context_t agent_ctx = NULL;
49 static int did_early_card_test;
50
51 struct cipher_parm_s 
52 {
53   ctrl_t ctrl;
54   assuan_context_t ctx;
55   unsigned char *ciphertext;
56   size_t ciphertextlen;
57 };
58
59 struct writecert_parm_s
60 {
61   assuan_context_t ctx;
62   const unsigned char *certdata;
63   size_t certdatalen;
64 };
65
66 struct writekey_parm_s
67 {
68   assuan_context_t ctx;
69   const unsigned char *keydata;
70   size_t keydatalen;
71 };
72
73 struct genkey_parm_s
74 {
75   ctrl_t ctrl;
76   assuan_context_t ctx;
77   const char *keyparms;
78 };
79
80 struct import_key_parm_s
81 {
82   ctrl_t ctrl;
83   assuan_context_t ctx;
84   const void *key;
85   size_t keylen;
86 };
87
88
89 static gpg_error_t learn_status_cb (void *opaque, const char *line);
90
91
92 \f
93 /* If RC is not 0, write an appropriate status message. */
94 static void
95 status_sc_op_failure (int rc)
96 {
97   switch (gpg_err_code (rc))
98     {
99     case 0:
100       break;
101     case GPG_ERR_CANCELED:
102       write_status_text (STATUS_SC_OP_FAILURE, "1");
103       break;
104     case GPG_ERR_BAD_PIN:
105       write_status_text (STATUS_SC_OP_FAILURE, "2");
106       break;
107     default:
108       write_status (STATUS_SC_OP_FAILURE);
109       break;
110     }
111 }  
112
113
114
115 /* Try to connect to the agent via socket or fork it off and work by
116    pipes.  Handle the server's initial greeting */
117 static int
118 start_agent (ctrl_t ctrl, int for_card)
119 {
120   int rc;
121
122   (void)ctrl;  /* Not yet used.  */
123
124   /* Fixme: We need a context for each thread or serialize the access
125      to the agent. */
126   if (agent_ctx)
127     rc = 0;
128   else
129     {
130       rc = start_new_gpg_agent (&agent_ctx,
131                                 GPG_ERR_SOURCE_DEFAULT,
132                                 opt.homedir,
133                                 opt.agent_program,
134                                 opt.lc_ctype, opt.lc_messages,
135                                 opt.session_env,
136                                 opt.verbose, DBG_ASSUAN,
137                                 NULL, NULL);
138       if (!rc)
139         {
140           /* Tell the agent that we support Pinentry notifications.
141              No error checking so that it will work also with older
142              agents.  */
143           assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
144                            NULL, NULL, NULL, NULL, NULL, NULL);
145         }
146     }
147
148   if (!rc && for_card && !did_early_card_test)
149     {
150       /* Request the serial number of the card for an early test.  */
151       struct agent_card_info_s info;
152
153       memset (&info, 0, sizeof info);
154       rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
155                             NULL, NULL, NULL, NULL,
156                             learn_status_cb, &info);
157       if (rc)
158         {
159           switch (gpg_err_code (rc))
160             {
161             case GPG_ERR_NOT_SUPPORTED:
162             case GPG_ERR_NO_SCDAEMON:
163               write_status_text (STATUS_CARDCTRL, "6");
164               break;
165             default:
166               write_status_text (STATUS_CARDCTRL, "4");
167               log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
168               break;
169             }
170         }
171
172       if (!rc && is_status_enabled () && info.serialno)
173         {
174           char *buf;
175           
176           buf = xasprintf ("3 %s", info.serialno);
177           write_status_text (STATUS_CARDCTRL, buf);
178           xfree (buf);
179         }
180
181       agent_release_card_info (&info);
182
183       if (!rc)
184         did_early_card_test = 1;
185     }
186
187   
188   return rc;
189 }
190
191
192 /* Return a new malloced string by unescaping the string S.  Escaping
193    is percent escaping and '+'/space mapping.  A binary nul will
194    silently be replaced by a 0xFF.  Function returns NULL to indicate
195    an out of memory status. */
196 static char *
197 unescape_status_string (const unsigned char *s)
198 {
199   return percent_plus_unescape (s, 0xff);
200 }
201
202
203 /* Take a 20 byte hexencoded string and put it into the the provided
204    20 byte buffer FPR in binary format. */
205 static int
206 unhexify_fpr (const char *hexstr, unsigned char *fpr)
207 {
208   const char *s;
209   int n;
210
211   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
212     ;
213   if (*s || (n != 40))
214     return 0; /* no fingerprint (invalid or wrong length). */
215   for (s=hexstr, n=0; *s; s += 2, n++)
216     fpr[n] = xtoi_2 (s);
217   return 1; /* okay */
218 }
219
220 /* Take the serial number from LINE and return it verbatim in a newly
221    allocated string.  We make sure that only hex characters are
222    returned. */
223 static char *
224 store_serialno (const char *line)
225 {
226   const char *s;
227   char *p;
228
229   for (s=line; hexdigitp (s); s++)
230     ;
231   p = xtrymalloc (s + 1 - line);
232   if (p)
233     {
234       memcpy (p, line, s-line);
235       p[s-line] = 0;
236     }
237   return p;
238 }
239
240
241 \f
242 /* This is a dummy data line callback.  */
243 static gpg_error_t
244 dummy_data_cb (void *opaque, const void *buffer, size_t length)
245 {
246   (void)opaque;
247   (void)buffer;
248   (void)length;
249   return 0;
250 }
251
252 /* A simple callback used to return the serialnumber of a card.  */
253 static gpg_error_t
254 get_serialno_cb (void *opaque, const char *line)
255 {
256   char **serialno = opaque;
257   const char *keyword = line;
258   const char *s;
259   int keywordlen, n;
260
261   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
262     ;
263   while (spacep (line))
264     line++;
265
266   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
267     {
268       if (*serialno)
269         return gpg_error (GPG_ERR_CONFLICT); /* Unexpected status line. */
270       for (n=0,s=line; hexdigitp (s); s++, n++)
271         ;
272       if (!n || (n&1)|| !(spacep (s) || !*s) )
273         return gpg_error (GPG_ERR_ASS_PARAMETER);
274       *serialno = xtrymalloc (n+1);
275       if (!*serialno)
276         return out_of_core ();
277       memcpy (*serialno, line, n);
278       (*serialno)[n] = 0;
279     }
280   
281   return 0;
282 }
283
284
285 /* This is the default inquiry callback.  It mainly handles the
286    Pinentry notifications.  */
287 static gpg_error_t
288 default_inq_cb (void *opaque, const char *line)
289 {
290   (void)opaque;
291
292   if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
293     {
294       /* There is no working server mode yet thus we use
295          AllowSetForegroundWindow window right here.  We might want to
296          do this anyway in case gpg is called on the console. */
297       gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
298       /* We do not pass errors to avoid breaking other code.  */
299     }
300   else
301     log_debug ("ignoring gpg-agent inquiry `%s'\n", line);
302
303   return 0;
304 }
305
306
307
308 /* Release the card info structure INFO. */
309 void
310 agent_release_card_info (struct agent_card_info_s *info)
311 {
312   if (!info)
313     return;
314
315   xfree (info->serialno); info->serialno = NULL;
316   xfree (info->apptype); info->apptype = NULL;
317   xfree (info->disp_name); info->disp_name = NULL;
318   xfree (info->disp_lang); info->disp_lang = NULL;
319   xfree (info->pubkey_url); info->pubkey_url = NULL;
320   xfree (info->login_data); info->login_data = NULL;
321   info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
322   info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
323 }
324
325 static gpg_error_t
326 learn_status_cb (void *opaque, const char *line)
327 {
328   struct agent_card_info_s *parm = opaque;
329   const char *keyword = line;
330   int keywordlen;
331   int i;
332
333   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
334     ;
335   while (spacep (line))
336     line++;
337
338   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
339     {
340       xfree (parm->serialno);
341       parm->serialno = store_serialno (line);
342       parm->is_v2 = (strlen (parm->serialno) >= 16 
343                      && xtoi_2 (parm->serialno+12) >= 2 );
344     }
345   else if (keywordlen == 7 && !memcmp (keyword, "APPTYPE", keywordlen))
346     {
347       xfree (parm->apptype);
348       parm->apptype = unescape_status_string (line);
349     }
350   else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
351     {
352       xfree (parm->disp_name);
353       parm->disp_name = unescape_status_string (line);
354     }
355   else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
356     {
357       xfree (parm->disp_lang);
358       parm->disp_lang = unescape_status_string (line);
359     }
360   else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
361     {
362       parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
363     }
364   else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
365     {
366       xfree (parm->pubkey_url);
367       parm->pubkey_url = unescape_status_string (line);
368     }
369   else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
370     {
371       xfree (parm->login_data);
372       parm->login_data = unescape_status_string (line);
373     }
374   else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
375     {
376       parm->sig_counter = strtoul (line, NULL, 0);
377     }
378   else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
379     {
380       char *p, *buf;
381
382       buf = p = unescape_status_string (line);
383       if (buf)
384         {
385           while (spacep (p))
386             p++;
387           parm->chv1_cached = atoi (p);
388           while (*p && !spacep (p))
389             p++;
390           while (spacep (p))
391             p++;
392           for (i=0; *p && i < 3; i++)
393             {
394               parm->chvmaxlen[i] = atoi (p);
395               while (*p && !spacep (p))
396                 p++;
397               while (spacep (p))
398                 p++;
399             }
400           for (i=0; *p && i < 3; i++)
401             {
402               parm->chvretry[i] = atoi (p);
403               while (*p && !spacep (p))
404                 p++;
405               while (spacep (p))
406                 p++;
407             }
408           xfree (buf);
409         }
410     }
411   else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen))
412     {
413       char *p, *p2, *buf;
414       int abool;
415
416       buf = p = unescape_status_string (line);
417       if (buf)
418         {
419           for (p = strtok (buf, " "); p; p = strtok (NULL, " "))
420             {
421               p2 = strchr (p, '=');
422               if (p2)
423                 {
424                   *p2++ = 0;
425                   abool = (*p2 == '1');
426                   if (!strcmp (p, "ki"))
427                     parm->extcap.ki = abool;
428                   else if (!strcmp (p, "aac"))
429                     parm->extcap.aac = abool;
430                 }
431             }
432           xfree (buf);
433         }
434     }
435   else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
436     {
437       int no = atoi (line);
438       while (*line && !spacep (line))
439         line++;
440       while (spacep (line))
441         line++;
442       if (no == 1)
443         parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
444       else if (no == 2)
445         parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
446       else if (no == 3)
447         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
448     }
449   else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
450     {
451       int no = atoi (line);
452       while (* line && !spacep (line))
453         line++;
454       while (spacep (line))
455         line++;
456       if (no == 1)
457         parm->fpr1time = strtoul (line, NULL, 10);
458       else if (no == 2)
459         parm->fpr2time = strtoul (line, NULL, 10);
460       else if (no == 3)
461         parm->fpr3time = strtoul (line, NULL, 10);
462     }
463   else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
464     {
465       int no = atoi (line);
466       while (*line && !spacep (line))
467         line++;
468       while (spacep (line))
469         line++;
470       if (no == 1)
471         parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
472       else if (no == 2)
473         parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
474       else if (no == 3)
475         parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
476     }
477   else if (keywordlen == 8 && !memcmp (keyword, "KEY-ATTR", keywordlen))
478     {
479       int keyno, algo, nbits;
480
481       sscanf (line, "%d %d %d", &keyno, &algo, &nbits);
482       keyno--;
483       if (keyno >= 0 && keyno < DIM (parm->key_attr))
484         {
485           parm->key_attr[keyno].algo = algo;
486           parm->key_attr[keyno].nbits = nbits;
487         }
488     }
489
490   return 0;
491 }
492
493 /* Call the agent to learn about a smartcard */
494 int
495 agent_learn (struct agent_card_info_s *info)
496 {
497   int rc;
498
499   rc = start_agent (NULL, 1);
500   if (rc)
501     return rc;
502
503   /* Send the serialno command to initialize the connection.  We don't
504      care about the data returned.  If the card has already been
505      initialized, this is a very fast command.  The main reason we
506      need to do this here is to handle a card removed case so that an
507      "l" command in --card-edit can be used to show ta newly inserted
508      card.  We request the openpgp card because that is what we
509      expect. */
510   rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
511                         NULL, NULL, NULL, NULL, NULL, NULL);
512   if (rc)
513     return rc;
514
515
516   memset (info, 0, sizeof *info);
517   rc = assuan_transact (agent_ctx, "SCD LEARN --force",
518                         dummy_data_cb, NULL, default_inq_cb, NULL,
519                         learn_status_cb, info);
520   /* Also try to get the key attributes.  */
521   if (!rc)
522     agent_scd_getattr ("KEY-ATTR", info);
523   
524   return rc;
525 }
526
527 /* Call the agent to retrieve a data object.  This function returns
528    the data in the same structure as used by the learn command.  It is
529    allowed to update such a structure using this commmand. */
530 int
531 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
532 {
533   int rc;
534   char line[ASSUAN_LINELENGTH];
535
536   if (!*name)
537     return gpg_error (GPG_ERR_INV_VALUE);
538
539   /* We assume that NAME does not need escaping. */
540   if (12 + strlen (name) > DIM(line)-1)
541     return gpg_error (GPG_ERR_TOO_LARGE);
542   stpcpy (stpcpy (line, "SCD GETATTR "), name); 
543
544   rc = start_agent (NULL, 1);
545   if (rc)
546     return rc;
547
548   rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
549                         learn_status_cb, info);
550   
551   return rc;
552 }
553
554 \f
555 /* Send an setattr command to the SCdaemon.  SERIALNO is not actually
556    used here but required by gpg 1.4's implementation of this code in
557    cardglue.c. */
558 int
559 agent_scd_setattr (const char *name,
560                    const unsigned char *value, size_t valuelen,
561                    const char *serialno)
562 {
563   int rc;
564   char line[ASSUAN_LINELENGTH];
565   char *p;
566
567   (void)serialno;
568
569   if (!*name || !valuelen)
570     return gpg_error (GPG_ERR_INV_VALUE);
571
572   /* We assume that NAME does not need escaping. */
573   if (12 + strlen (name) > DIM(line)-1)
574     return gpg_error (GPG_ERR_TOO_LARGE);
575       
576   p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
577   *p++ = ' ';
578   for (; valuelen; value++, valuelen--)
579     {
580       if (p >= line + DIM(line)-5 )
581         return gpg_error (GPG_ERR_TOO_LARGE);
582       if (*value < ' ' || *value == '+' || *value == '%')
583         {
584           sprintf (p, "%%%02X", *value);
585           p += 3;
586         }
587       else if (*value == ' ')
588         *p++ = '+';
589       else
590         *p++ = *value;
591     }
592   *p = 0;
593
594   rc = start_agent (NULL, 1);
595   if (!rc)
596     {
597       rc = assuan_transact (agent_ctx, line, NULL, NULL, 
598                             default_inq_cb, NULL, NULL, NULL);
599     }
600
601   status_sc_op_failure (rc);
602   return rc;
603 }
604
605
606 \f
607 /* Handle a CERTDATA inquiry.  Note, we only send the data,
608    assuan_transact takes care of flushing and writing the END
609    command. */
610 static gpg_error_t
611 inq_writecert_parms (void *opaque, const char *line)
612 {
613   int rc;
614   struct writecert_parm_s *parm = opaque; 
615
616   if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8]))
617     {
618       rc = assuan_send_data (parm->ctx, parm->certdata, parm->certdatalen);
619     }
620   else
621     rc = default_inq_cb (opaque, line);
622
623   return rc;
624 }
625
626
627 /* Send a WRITECERT command to the SCdaemon. */
628 int 
629 agent_scd_writecert (const char *certidstr,
630                      const unsigned char *certdata, size_t certdatalen)
631 {
632   int rc;
633   char line[ASSUAN_LINELENGTH];
634   struct writecert_parm_s parms;
635
636   rc = start_agent (NULL, 1);
637   if (rc)
638     return rc;
639
640   memset (&parms, 0, sizeof parms);
641
642   snprintf (line, DIM(line)-1, "SCD WRITECERT %s", certidstr);
643   line[DIM(line)-1] = 0;
644   parms.ctx = agent_ctx;
645   parms.certdata = certdata;
646   parms.certdatalen = certdatalen;
647   
648   rc = assuan_transact (agent_ctx, line, NULL, NULL,
649                         inq_writecert_parms, &parms, NULL, NULL);
650
651   return rc;
652 }
653
654
655 \f
656 /* Handle a KEYDATA inquiry.  Note, we only send the data,
657    assuan_transact takes care of flushing and writing the end */
658 static gpg_error_t
659 inq_writekey_parms (void *opaque, const char *line)
660 {
661   int rc;
662   struct writekey_parm_s *parm = opaque; 
663
664   if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
665     {
666       rc = assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
667     }
668   else
669     rc = default_inq_cb (opaque, line);
670
671   return rc;
672 }
673
674
675 /* Send a WRITEKEY command to the SCdaemon. */
676 int 
677 agent_scd_writekey (int keyno, const char *serialno,
678                     const unsigned char *keydata, size_t keydatalen)
679 {
680   int rc;
681   char line[ASSUAN_LINELENGTH];
682   struct writekey_parm_s parms;
683
684   (void)serialno;
685
686   rc = start_agent (NULL, 1);
687   if (rc)
688     return rc;
689
690   memset (&parms, 0, sizeof parms);
691
692   snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
693   line[DIM(line)-1] = 0;
694   parms.ctx = agent_ctx;
695   parms.keydata = keydata;
696   parms.keydatalen = keydatalen;
697   
698   rc = assuan_transact (agent_ctx, line, NULL, NULL,
699                         inq_writekey_parms, &parms, NULL, NULL);
700
701   status_sc_op_failure (rc);
702   return rc;
703 }
704
705
706 \f
707 /* Status callback for the SCD GENKEY command. */
708 static gpg_error_t
709 scd_genkey_cb (void *opaque, const char *line)
710 {
711   struct agent_card_genkey_s *parm = opaque;
712   const char *keyword = line;
713   int keywordlen;
714   gpg_error_t rc;
715
716   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
717     ;
718   while (spacep (line))
719     line++;
720
721   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
722     {
723       parm->fprvalid = unhexify_fpr (line, parm->fpr);
724     }
725   else if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
726     {
727       gcry_mpi_t a;
728       const char *name = line;
729
730       while (*line && !spacep (line))
731         line++;
732       while (spacep (line))
733         line++;
734
735       rc = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL);
736       if (rc)
737         log_error ("error parsing received key data: %s\n", gpg_strerror (rc));
738       else if (*name == 'n' && spacep (name+1))
739         parm->n = a;
740       else if (*name == 'e' && spacep (name+1))
741         parm->e = a;
742       else
743         {
744           log_info ("unknown parameter name in received key data\n");
745           gcry_mpi_release (a);
746         }
747     }
748   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
749     {
750       parm->created_at = (u32)strtoul (line, NULL, 10);
751     }
752   else if (keywordlen == 8 && !memcmp (keyword, "PROGRESS", keywordlen))
753     {
754       write_status_text (STATUS_PROGRESS, line);
755     }
756
757   return 0;
758 }
759
760 /* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
761    this implementation.  If CREATEDATE has been given, it will be
762    passed to SCDAEMON so that the key can be created with this
763    timestamp; note the user needs to use the returned timestamp as old
764    versions of scddaemon don't support this option.  */
765 int
766 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
767                   const char *serialno, u32 createtime)
768 {
769   int rc;
770   char line[ASSUAN_LINELENGTH];
771   gnupg_isotime_t tbuf;
772
773   (void)serialno;
774
775   rc = start_agent (NULL, 1);
776   if (rc)
777     return rc;
778
779   if (createtime)
780     epoch2isotime (tbuf, createtime);
781   else
782     *tbuf = 0;
783
784   memset (info, 0, sizeof *info);
785   snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
786             *tbuf? "--timestamp=":"", tbuf,
787             force? "--force":"", 
788             keyno);
789   line[DIM(line)-1] = 0;
790
791   memset (info, 0, sizeof *info);
792   rc = assuan_transact (agent_ctx, line,
793                         NULL, NULL, default_inq_cb, NULL,
794                         scd_genkey_cb, info);
795   
796   status_sc_op_failure (rc);
797   return rc;
798 }
799
800
801
802 \f
803 /* Issue an SCD SERIALNO openpgp command and if SERIALNO is not NULL
804    ask the user to insert the requested card.  */
805 gpg_error_t
806 select_openpgp (const char *serialno)
807 {
808   gpg_error_t err;
809
810   /* Send the serialno command to initialize the connection.  Without
811      a given S/N we don't care about the data returned.  If the card
812      has already been initialized, this is a very fast command.  We
813      request the openpgp card because that is what we expect. 
814
815      Note that an opt.limit_card_insert_tries of 1 means: No tries at
816      all whereas 0 means do not limit the number of tries.  Due to the
817      sue of a pinentry prompt with a cancel option we use it here in a
818      boolean sense.  */
819   if (!serialno || opt.limit_card_insert_tries == 1)
820     err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
821                            NULL, NULL, NULL, NULL, NULL, NULL);
822   else
823     {
824       char *this_sn = NULL;
825       char *desc;
826       int ask;
827       char *want_sn;
828       char *p;
829       
830       want_sn = xtrystrdup (serialno);
831       if (!want_sn)
832         return gpg_error_from_syserror ();
833       p = strchr (want_sn, '/');
834       if (p)
835         *p = 0;
836
837       do 
838         {
839           ask = 0;
840           err = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
841                                  NULL, NULL, NULL, NULL, 
842                                  get_serialno_cb, &this_sn);
843           if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT)
844             ask = 1; 
845           else if (gpg_err_code (err) == GPG_ERR_NOT_SUPPORTED)
846             ask = 2;
847           else if (err)
848             ;
849           else if (this_sn)
850             {
851               if (strcmp (want_sn, this_sn))
852                 ask = 2;
853             }
854
855           xfree (this_sn);
856           this_sn = NULL;
857                   
858           if (ask)
859             {
860               char *formatted = NULL;
861               char *ocodeset = i18n_switchto_utf8 ();
862
863               if (!strncmp (want_sn, "D27600012401", 12) 
864                   && strlen (want_sn) == 32 )
865                 formatted = xtryasprintf ("(%.4s) %.8s",
866                                           want_sn + 16, want_sn + 20);
867               
868               err = 0;
869               desc = xtryasprintf 
870                 ("%s:\n\n"
871                  "  \"%s\"",
872                  ask == 1
873                  ? _("Please insert the card with serial number")
874                  : _("Please remove the current card and "
875                      "insert the one with serial number"),
876                  formatted? formatted : want_sn);
877               if (!desc)
878                 err = gpg_error_from_syserror ();
879               xfree (formatted);
880               i18n_switchback (ocodeset);
881               if (!err)
882                 err = gpg_agent_get_confirmation (desc);
883               xfree (desc);
884             }
885         }
886       while (ask && !err);
887       xfree (want_sn);
888     }
889
890   return err;
891 }
892
893
894 \f
895 static gpg_error_t
896 membuf_data_cb (void *opaque, const void *buffer, size_t length)
897 {
898   membuf_t *data = opaque;
899
900   if (buffer)
901     put_membuf (data, buffer, length);
902   return 0;
903 }
904   
905 /* Send a sign command to the scdaemon via gpg-agent's pass thru
906    mechanism. */
907 int
908 agent_scd_pksign (const char *serialno, int hashalgo,
909                   const unsigned char *indata, size_t indatalen,
910                   unsigned char **r_buf, size_t *r_buflen)
911 {
912   int rc, i;
913   char *p, line[ASSUAN_LINELENGTH];
914   membuf_t data;
915   size_t len;
916
917   /* Note, hashalgo is not yet used but hardwired to SHA1 in SCdaemon. */
918
919   *r_buf = NULL;
920   *r_buflen = 0;
921
922   rc = start_agent (NULL, 1);
923   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
924       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
925     rc = 0; /* We check later.  */
926   if (rc)
927     return rc;
928
929   if (indatalen*2 + 50 > DIM(line))
930     return gpg_error (GPG_ERR_GENERAL);
931
932   rc = select_openpgp (serialno);
933   if (rc)
934     return rc;
935
936   sprintf (line, "SCD SETDATA ");
937   p = line + strlen (line);
938   for (i=0; i < indatalen ; i++, p += 2 )
939     sprintf (p, "%02X", indata[i]);
940   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
941   if (rc)
942     return rc;
943
944   init_membuf (&data, 1024);
945 #if 0
946   if (!hashalgo) /* Temporary test hack. */
947     snprintf (line, DIM(line)-1, "SCD PKAUTH %s", serialno);
948   else
949 #endif
950     snprintf (line, DIM(line)-1, "SCD PKSIGN %s%s",
951               hashalgo == GCRY_MD_RMD160? "--hash=rmd160 " : "",
952               serialno);
953   line[DIM(line)-1] = 0;
954   rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
955                         default_inq_cb, NULL, NULL, NULL);
956   if (rc)
957     {
958       xfree (get_membuf (&data, &len));
959     }
960   else
961     *r_buf = get_membuf (&data, r_buflen);
962
963   status_sc_op_failure (rc);
964   return rc;
965 }
966
967
968 /* Decrypt INDATA of length INDATALEN using the card identified by
969    SERIALNO.  Return the plaintext in a nwly allocated buffer stored
970    at the address of R_BUF.
971
972    Note, we currently support only RSA or more exactly algorithms
973    taking one input data element. */
974 int
975 agent_scd_pkdecrypt (const char *serialno,
976                      const unsigned char *indata, size_t indatalen,
977                      unsigned char **r_buf, size_t *r_buflen)
978 {
979   int rc, i;
980   char *p, line[ASSUAN_LINELENGTH];
981   membuf_t data;
982   size_t len;
983
984   *r_buf = NULL;
985   rc = start_agent (NULL, 1);
986   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
987       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
988     rc = 0; /* We check later.  */
989   if (rc)
990     return rc;
991
992   /* FIXME: use secure memory where appropriate */
993   if (indatalen*2 + 50 > DIM(line))
994     return gpg_error (GPG_ERR_GENERAL);
995
996   rc = select_openpgp (serialno);
997   if (rc)
998     return rc;
999   
1000   sprintf (line, "SCD SETDATA ");
1001   p = line + strlen (line);
1002   for (i=0; i < indatalen ; i++, p += 2 )
1003     sprintf (p, "%02X", indata[i]);
1004   rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1005   if (rc)
1006     return rc;
1007
1008   init_membuf (&data, 1024);
1009   snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
1010   line[DIM(line)-1] = 0;
1011   rc = assuan_transact (agent_ctx, line,
1012                         membuf_data_cb, &data,
1013                         default_inq_cb, NULL, NULL, NULL);
1014   if (rc)
1015     {
1016       xfree (get_membuf (&data, &len));
1017     }
1018   else
1019     {
1020       *r_buf = get_membuf (&data, r_buflen);
1021       if (!*r_buf)
1022         rc = gpg_error (GPG_ERR_ENOMEM);
1023     }
1024
1025   status_sc_op_failure (rc);
1026   return rc;
1027 }
1028
1029
1030 \f
1031 /* Send a READCERT command to the SCdaemon. */
1032 int 
1033 agent_scd_readcert (const char *certidstr,
1034                     void **r_buf, size_t *r_buflen)
1035 {
1036   int rc;
1037   char line[ASSUAN_LINELENGTH];
1038   membuf_t data;
1039   size_t len;
1040
1041   *r_buf = NULL;
1042   rc = start_agent (NULL, 1);
1043   if (rc)
1044     return rc;
1045
1046   init_membuf (&data, 2048);
1047
1048   snprintf (line, DIM(line)-1, "SCD READCERT %s", certidstr);
1049   line[DIM(line)-1] = 0;
1050   rc = assuan_transact (agent_ctx, line,
1051                         membuf_data_cb, &data,
1052                         default_inq_cb, NULL, NULL, NULL);
1053   if (rc)
1054     {
1055       xfree (get_membuf (&data, &len));
1056       return rc;
1057     }
1058   *r_buf = get_membuf (&data, r_buflen);
1059   if (!*r_buf)
1060     return gpg_error (GPG_ERR_ENOMEM);
1061
1062   return 0;
1063 }
1064
1065
1066 \f
1067 /* Change the PIN of an OpenPGP card or reset the retry counter.
1068    CHVNO 1: Change the PIN
1069          2: For v1 cards: Same as 1.
1070             For v2 cards: Reset the PIN using the Reset Code.
1071          3: Change the admin PIN
1072        101: Set a new PIN and reset the retry counter
1073        102: For v1 cars: Same as 101.
1074             For v2 cards: Set a new Reset Code.
1075    SERIALNO is not used.
1076  */
1077 int
1078 agent_scd_change_pin (int chvno, const char *serialno)
1079 {
1080   int rc;
1081   char line[ASSUAN_LINELENGTH];
1082   const char *reset = "";
1083
1084   (void)serialno;
1085
1086   if (chvno >= 100)
1087     reset = "--reset";
1088   chvno %= 100;
1089
1090   rc = start_agent (NULL, 1);
1091   if (rc)
1092     return rc;
1093
1094   snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
1095   line[DIM(line)-1] = 0;
1096   rc = assuan_transact (agent_ctx, line, NULL, NULL,
1097                         default_inq_cb, NULL, NULL, NULL);
1098   status_sc_op_failure (rc);
1099   return rc;
1100 }
1101
1102
1103 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
1104    number of the card - optionally followed by the fingerprint;
1105    however the fingerprint is ignored here. */
1106 int
1107 agent_scd_checkpin  (const char *serialno)
1108 {
1109   int rc;
1110   char line[ASSUAN_LINELENGTH];
1111
1112   rc = start_agent (NULL, 1);
1113   if (rc)
1114     return rc;
1115
1116   snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno);
1117   line[DIM(line)-1] = 0;
1118   rc = assuan_transact (agent_ctx, line,
1119                         NULL, NULL,
1120                         default_inq_cb, NULL, NULL, NULL);
1121   status_sc_op_failure (rc);
1122   return rc;
1123 }
1124
1125
1126 /* Dummy function, only used by the gpg 1.4 implementation. */
1127 void
1128 agent_clear_pin_cache (const char *sn)
1129 {
1130   (void)sn;
1131 }
1132
1133
1134
1135 \f
1136 /* Note: All strings shall be UTF-8. On success the caller needs to
1137    free the string stored at R_PASSPHRASE. On error NULL will be
1138    stored at R_PASSPHRASE and an appropriate fpf error code
1139    returned. */
1140 gpg_error_t
1141 agent_get_passphrase (const char *cache_id,
1142                       const char *err_msg,
1143                       const char *prompt,
1144                       const char *desc_msg,
1145                       int repeat,
1146                       int check,
1147                       char **r_passphrase)
1148 {
1149   int rc;
1150   char line[ASSUAN_LINELENGTH];
1151   char *arg1 = NULL;
1152   char *arg2 = NULL;  
1153   char *arg3 = NULL; 
1154   char *arg4 = NULL;
1155   membuf_t data;
1156
1157   *r_passphrase = NULL;
1158
1159   rc = start_agent (NULL, 0);
1160   if (rc)
1161     return rc;
1162
1163   /* Check that the gpg-agent understands the repeat option.  */
1164   if (assuan_transact (agent_ctx, 
1165                        "GETINFO cmd_has_option GET_PASSPHRASE repeat",
1166                        NULL, NULL, NULL, NULL, NULL, NULL))
1167     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1168
1169   if (cache_id && *cache_id)
1170     if (!(arg1 = percent_plus_escape (cache_id)))
1171       goto no_mem;
1172   if (err_msg && *err_msg)
1173     if (!(arg2 = percent_plus_escape (err_msg)))
1174       goto no_mem;
1175   if (prompt && *prompt)
1176     if (!(arg3 = percent_plus_escape (prompt)))
1177       goto no_mem;
1178   if (desc_msg && *desc_msg)
1179     if (!(arg4 = percent_plus_escape (desc_msg)))
1180       goto no_mem;
1181
1182   snprintf (line, DIM(line)-1, 
1183             "GET_PASSPHRASE --data --repeat=%d%s -- %s %s %s %s", 
1184             repeat, 
1185             check? " --check --qualitybar":"",
1186             arg1? arg1:"X",
1187             arg2? arg2:"X",
1188             arg3? arg3:"X",
1189             arg4? arg4:"X");
1190   line[DIM(line)-1] = 0;
1191   xfree (arg1);
1192   xfree (arg2);
1193   xfree (arg3);
1194   xfree (arg4);
1195
1196   init_membuf_secure (&data, 64);
1197   rc = assuan_transact (agent_ctx, line, 
1198                         membuf_data_cb, &data,
1199                         default_inq_cb, NULL, NULL, NULL);
1200
1201   if (rc)
1202     xfree (get_membuf (&data, NULL));
1203   else 
1204     {
1205       put_membuf (&data, "", 1);
1206       *r_passphrase = get_membuf (&data, NULL);
1207       if (!*r_passphrase)
1208         rc = gpg_error_from_syserror ();
1209     }
1210   return rc;
1211  no_mem:
1212   rc = gpg_error_from_syserror ();
1213   xfree (arg1);
1214   xfree (arg2);
1215   xfree (arg3);
1216   xfree (arg4);
1217   return rc;
1218 }
1219
1220
1221 gpg_error_t
1222 agent_clear_passphrase (const char *cache_id)
1223 {
1224   int rc;
1225   char line[ASSUAN_LINELENGTH];
1226
1227   if (!cache_id || !*cache_id)
1228     return 0;
1229
1230   rc = start_agent (NULL, 0);
1231   if (rc)
1232     return rc;
1233
1234   snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
1235   line[DIM(line)-1] = 0;
1236   return assuan_transact (agent_ctx, line, NULL, NULL,
1237                           default_inq_cb, NULL, NULL, NULL);
1238 }
1239
1240
1241 /* Ask the agent to pop up a confirmation dialog with the text DESC
1242    and an okay and cancel button. */
1243 gpg_error_t
1244 gpg_agent_get_confirmation (const char *desc)
1245 {
1246   int rc;
1247   char *tmp;
1248   char line[ASSUAN_LINELENGTH];
1249
1250   rc = start_agent (NULL, 0);
1251   if (rc)
1252     return rc;
1253
1254   tmp = percent_plus_escape (desc);
1255   if (!tmp)
1256     return gpg_error_from_syserror ();
1257   snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", tmp);
1258   line[DIM(line)-1] = 0;
1259   xfree (tmp);
1260
1261   rc = assuan_transact (agent_ctx, line, NULL, NULL,
1262                         default_inq_cb, NULL, NULL, NULL);
1263   return rc;
1264 }
1265
1266
1267 /* Return the S2K iteration count as computed by gpg-agent.  */
1268 gpg_error_t
1269 agent_get_s2k_count (unsigned long *r_count)
1270 {
1271   gpg_error_t err;
1272   membuf_t data;
1273   char *buf;
1274
1275   *r_count = 0;
1276
1277   err = start_agent (NULL, 0);
1278   if (err)
1279     return err;
1280
1281   init_membuf (&data, 32);
1282   err = assuan_transact (agent_ctx, "GETINFO s2k_count", 
1283                         membuf_data_cb, &data,
1284                         NULL, NULL, NULL, NULL);
1285   if (err)
1286     xfree (get_membuf (&data, NULL));
1287   else 
1288     {
1289       put_membuf (&data, "", 1);
1290       buf = get_membuf (&data, NULL);
1291       if (!buf)
1292         err = gpg_error_from_syserror ();
1293       else
1294         {
1295           *r_count = strtoul (buf, NULL, 10);
1296           xfree (buf);
1297         }
1298     }
1299   return err;
1300 }
1301
1302
1303 \f
1304 /* Ask the agent whether a secret key for the given public key is
1305    available.  Returns 0 if available.  */
1306 gpg_error_t
1307 agent_probe_secret_key (ctrl_t ctrl, PKT_public_key *pk)
1308 {
1309   gpg_error_t err;
1310   char line[ASSUAN_LINELENGTH];
1311   char *hexgrip;
1312
1313   err = start_agent (ctrl, 0);
1314   if (err)
1315     return err;
1316
1317   err = hexkeygrip_from_pk (pk, &hexgrip);
1318   if (err)
1319     return err;
1320
1321   snprintf (line, sizeof line, "HAVEKEY %s", hexgrip);
1322   xfree (hexgrip);
1323
1324   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1325   return err;
1326 }
1327
1328
1329 \f
1330 static gpg_error_t
1331 keyinfo_status_cb (void *opaque, const char *line)
1332 {
1333   char **serialno = opaque;
1334   const char *s, *s2;
1335
1336   if (!strncmp (line, "KEYINFO ", 8) && !*serialno)
1337     {
1338       s = strchr (line+8, ' ');
1339       if (s && s[1] == 'T' && s[2] == ' ' && s[3])
1340         {
1341           s += 3;
1342           s2 = strchr (s, ' ');
1343           if ( s2 > s )
1344             {
1345               *serialno = xtrymalloc ((s2 - s)+1);
1346               if (*serialno)
1347                 {
1348                   memcpy (*serialno, s, s2 - s);
1349                   (*serialno)[s2 - s] = 0;
1350                 }
1351             }
1352         }
1353     }
1354   return 0;
1355 }
1356
1357
1358 /* Return the serial number for a secret key.  If the returned serial
1359    number is NULL, the key is not stored on a smartcard.  Caller needs
1360    to free R_SERIALNO.  */
1361 gpg_error_t
1362 agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
1363 {
1364   gpg_error_t err;
1365   char line[ASSUAN_LINELENGTH];
1366   char *serialno = NULL;
1367
1368   *r_serialno = NULL;
1369
1370   err = start_agent (ctrl, 0);
1371   if (err)
1372     return err;
1373
1374   if (!hexkeygrip || strlen (hexkeygrip) != 40)
1375     return gpg_error (GPG_ERR_INV_VALUE);
1376
1377   snprintf (line, DIM(line)-1, "KEYINFO %s", hexkeygrip);
1378   line[DIM(line)-1] = 0;
1379
1380   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
1381                          keyinfo_status_cb, &serialno);
1382   if (!err && serialno)
1383     {
1384       /* Sanity check for bad characters.  */
1385       if (strpbrk (serialno, ":\n\r"))
1386         err = GPG_ERR_INV_VALUE;
1387     }
1388   if (err)
1389     xfree (serialno);
1390   else
1391     *r_serialno = serialno;
1392   return err;
1393 }
1394
1395 \f
1396 /* Status callback for agent_import_key and agent_genkey.  */
1397 static gpg_error_t
1398 cache_nonce_status_cb (void *opaque, const char *line)
1399 {
1400   char **cache_nonce = opaque;
1401   const char *keyword = line;
1402   int keywordlen;
1403
1404   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1405     ;
1406   while (spacep (line))
1407     line++;
1408
1409   if (keywordlen == 11 && !memcmp (keyword, "CACHE_NONCE", keywordlen))
1410     {
1411       if (cache_nonce)
1412         {
1413           xfree (*cache_nonce);
1414           *cache_nonce = xtrystrdup (line);
1415         }
1416     }
1417
1418   return 0;
1419 }
1420
1421
1422 \f
1423 /* Handle a KEYPARMS inquiry.  Note, we only send the data,
1424    assuan_transact takes care of flushing and writing the end */
1425 static gpg_error_t
1426 inq_genkey_parms (void *opaque, const char *line)
1427 {
1428   struct genkey_parm_s *parm = opaque; 
1429   gpg_error_t err;
1430
1431   if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
1432     {
1433       err = assuan_send_data (parm->ctx,
1434                               parm->keyparms, strlen (parm->keyparms));
1435     }
1436   else
1437     err = default_inq_cb (parm->ctrl, line);
1438
1439   return err; 
1440 }
1441
1442
1443 /* Call the agent to generate a new key.  KEYPARMS is the usual
1444    S-expression giving the parameters of the key.  gpg-agent passes it
1445    gcry_pk_genkey.  */
1446 gpg_error_t
1447 agent_genkey (ctrl_t ctrl, char **cache_nonce_addr,
1448               const char *keyparms, gcry_sexp_t *r_pubkey)
1449 {
1450   gpg_error_t err;
1451   struct genkey_parm_s gk_parm;
1452   membuf_t data;
1453   size_t len;
1454   unsigned char *buf;
1455   char line[ASSUAN_LINELENGTH];
1456
1457   *r_pubkey = NULL;
1458   err = start_agent (ctrl, 0);
1459   if (err)
1460     return err;
1461
1462   err = assuan_transact (agent_ctx, "RESET", 
1463                          NULL, NULL, NULL, NULL, NULL, NULL);
1464   if (err)
1465     return err;
1466
1467   init_membuf (&data, 1024);
1468   gk_parm.ctrl     = ctrl;
1469   gk_parm.ctx      = agent_ctx;
1470   gk_parm.keyparms = keyparms;
1471   snprintf (line, sizeof line, "GENKEY%s%s",
1472             cache_nonce_addr && *cache_nonce_addr? " ":"",
1473             cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
1474   err = assuan_transact (agent_ctx, line,
1475                          membuf_data_cb, &data, 
1476                          inq_genkey_parms, &gk_parm, 
1477                          cache_nonce_status_cb, cache_nonce_addr);
1478   if (err)
1479     {
1480       xfree (get_membuf (&data, &len));
1481       return err;
1482     }
1483   
1484   buf = get_membuf (&data, &len);
1485   if (!buf)
1486     err = gpg_error_from_syserror ();
1487   else
1488     {
1489       err = gcry_sexp_sscan (r_pubkey, NULL, buf, len);
1490       xfree (buf);
1491     }
1492   return err;
1493 }
1494
1495
1496
1497 \f
1498 /* FIXME: Call the agent to read the public key part for a given keygrip.  If
1499    FROMCARD is true, the key is directly read from the current
1500    smartcard. In this case HEXKEYGRIP should be the keyID
1501    (e.g. OPENPGP.3). */
1502 /* int */
1503 /* agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, */
1504 /*                ksba_sexp_t *r_pubkey) */
1505 /* { */
1506 /*   int rc; */
1507 /*   membuf_t data; */
1508 /*   size_t len; */
1509 /*   unsigned char *buf; */
1510 /*   char line[ASSUAN_LINELENGTH]; */
1511
1512 /*   *r_pubkey = NULL; */
1513 /*   rc = start_agent (ctrl); */
1514 /*   if (rc) */
1515 /*     return rc; */
1516
1517 /*   rc = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL); */
1518 /*   if (rc) */
1519 /*     return rc; */
1520
1521 /*   snprintf (line, DIM(line)-1, "%sREADKEY %s", */
1522 /*             fromcard? "SCD ":"", hexkeygrip); */
1523 /*   line[DIM(line)-1] = 0; */
1524
1525 /*   init_membuf (&data, 1024); */
1526 /*   rc = assuan_transact (agent_ctx, line, */
1527 /*                         membuf_data_cb, &data,  */
1528 /*                         default_inq_cb, ctrl, NULL, NULL); */
1529 /*   if (rc) */
1530 /*     { */
1531 /*       xfree (get_membuf (&data, &len)); */
1532 /*       return rc; */
1533 /*     } */
1534 /*   buf = get_membuf (&data, &len); */
1535 /*   if (!buf) */
1536 /*     return gpg_error (GPG_ERR_ENOMEM); */
1537 /*   if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) */
1538 /*     { */
1539 /*       xfree (buf); */
1540 /*       return gpg_error (GPG_ERR_INV_SEXP); */
1541 /*     } */
1542 /*   *r_pubkey = buf; */
1543 /*   return 0; */
1544 /* } */
1545
1546
1547 \f
1548 /* Call the agent to do a sign operation using the key identified by
1549    the hex string KEYGRIP.  DESC is a description of the key to be
1550    displayed if the agent needs to ask for the PIN.  DIGEST and
1551    DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
1552    used to compute the digest.  If CACHE_NONCE is used the agent is
1553    advised to firts try a passphrase associated with that nonce. */
1554 gpg_error_t
1555 agent_pksign (ctrl_t ctrl, const char *cache_nonce,
1556               const char *keygrip, const char *desc,
1557               unsigned char *digest, size_t digestlen, int digestalgo,
1558               gcry_sexp_t *r_sigval)
1559 {
1560   gpg_error_t err;
1561   int i;
1562   char *p, line[ASSUAN_LINELENGTH];
1563   membuf_t data;
1564
1565   *r_sigval = NULL;
1566   err = start_agent (ctrl, 0);
1567   if (err)
1568     return err;
1569
1570   if (digestlen*2 + 50 > DIM(line))
1571     return gpg_error (GPG_ERR_GENERAL);
1572
1573   err = assuan_transact (agent_ctx, "RESET",
1574                          NULL, NULL, NULL, NULL, NULL, NULL);
1575   if (err)
1576     return err;
1577
1578   snprintf (line, DIM(line)-1, "SIGKEY %s", keygrip);
1579   line[DIM(line)-1] = 0;
1580   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1581   if (err)
1582     return err;
1583
1584   if (desc)
1585     {
1586       snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
1587       line[DIM(line)-1] = 0;
1588       err = assuan_transact (agent_ctx, line,
1589                             NULL, NULL, NULL, NULL, NULL, NULL);
1590       if (err)
1591         return err;
1592     }
1593
1594   snprintf (line, sizeof line, "SETHASH %d ", digestalgo);
1595   p = line + strlen (line);
1596   for (i=0; i < digestlen ; i++, p += 2 )
1597     sprintf (p, "%02X", digest[i]);
1598   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1599   if (err)
1600     return err;
1601
1602   init_membuf (&data, 1024);
1603
1604   snprintf (line, sizeof line, "PKSIGN%s%s",
1605             cache_nonce? " -- ":"",
1606             cache_nonce? cache_nonce:"");
1607   err = assuan_transact (agent_ctx, line,
1608                         membuf_data_cb, &data, default_inq_cb, ctrl,
1609                         NULL, NULL);
1610   if (err)
1611     xfree (get_membuf (&data, NULL));
1612   else
1613     {
1614       unsigned char *buf;
1615       size_t len;
1616
1617       buf = get_membuf (&data, &len);
1618       if (!buf)
1619         err = gpg_error_from_syserror ();
1620       else
1621         {
1622           err = gcry_sexp_sscan (r_sigval, NULL, buf, len);
1623           xfree (buf);
1624         }
1625     }
1626   return err;
1627 }
1628
1629
1630 \f
1631 /* Handle a CIPHERTEXT inquiry.  Note, we only send the data,
1632    assuan_transact takes care of flushing and writing the END. */
1633 static gpg_error_t
1634 inq_ciphertext_cb (void *opaque, const char *line)
1635 {
1636   struct cipher_parm_s *parm = opaque; 
1637   int rc;
1638
1639   if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10]))
1640     {
1641       assuan_begin_confidential (parm->ctx);
1642       rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen);
1643       assuan_end_confidential (parm->ctx);
1644     }
1645   else
1646     rc = default_inq_cb (parm->ctrl, line);
1647
1648   return rc; 
1649 }
1650
1651
1652 /* Call the agent to do a decrypt operation using the key identified
1653    by the hex string KEYGRIP and the input data S_CIPHERTEXT.  On the
1654    success the decoded value is stored verbatim at R_BUF and its
1655    length at R_BUF; the callers needs to release it.  */
1656 gpg_error_t
1657 agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
1658                  gcry_sexp_t s_ciphertext,
1659                  unsigned char **r_buf, size_t *r_buflen)
1660 {
1661   gpg_error_t err;
1662   char line[ASSUAN_LINELENGTH];
1663   membuf_t data;
1664   size_t n, len;
1665   char *p, *buf, *endp;
1666   
1667   if (!keygrip || strlen(keygrip) != 40 || !s_ciphertext || !r_buf || !r_buflen)
1668     return gpg_error (GPG_ERR_INV_VALUE);
1669   *r_buf = NULL;
1670
1671   err = start_agent (ctrl, 0);
1672   if (err)
1673     return err;
1674
1675   err = assuan_transact (agent_ctx, "RESET",
1676                          NULL, NULL, NULL, NULL, NULL, NULL);
1677   if (err)
1678     return err;
1679
1680   snprintf (line, sizeof line, "SETKEY %s", keygrip);
1681   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1682   if (err)
1683     return err;
1684
1685   if (desc)
1686     {
1687       snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
1688       line[DIM(line)-1] = 0;
1689       err = assuan_transact (agent_ctx, line,
1690                             NULL, NULL, NULL, NULL, NULL, NULL);
1691       if (err)
1692         return err;
1693     }
1694
1695   init_membuf_secure (&data, 1024);
1696   {
1697     struct cipher_parm_s parm;
1698     
1699     parm.ctrl = ctrl;
1700     parm.ctx = agent_ctx;
1701     err = make_canon_sexp (s_ciphertext, &parm.ciphertext, &parm.ciphertextlen);
1702     if (err)
1703       return err;
1704     err = assuan_transact (agent_ctx, "PKDECRYPT",
1705                            membuf_data_cb, &data,
1706                            inq_ciphertext_cb, &parm, NULL, NULL);
1707     xfree (parm.ciphertext);
1708   }
1709   if (err)
1710     {
1711       xfree (get_membuf (&data, &len));
1712       return err;
1713     }
1714
1715   put_membuf (&data, "", 1); /* Make sure it is 0 terminated.  */
1716   buf = get_membuf (&data, &len);
1717   if (!buf)
1718     return gpg_error_from_syserror ();
1719   assert (len); /* (we forced Nul termination.)  */
1720
1721   if (*buf != '(')
1722     {
1723       xfree (buf);
1724       return gpg_error (GPG_ERR_INV_SEXP);
1725     }
1726
1727   if (len < 13 || memcmp (buf, "(5:value", 8) ) /* "(5:valueN:D)\0" */
1728     {
1729       xfree (buf);
1730       return gpg_error (GPG_ERR_INV_SEXP);
1731     }
1732   len -= 11;   /* Count only the data of the second part. */
1733   p = buf + 8; /* Skip leading parenthesis and the value tag. */
1734
1735   n = strtoul (p, &endp, 10);
1736   if (!n || *endp != ':')
1737     {
1738       xfree (buf);
1739       return gpg_error (GPG_ERR_INV_SEXP);
1740     }
1741   endp++;
1742   if (endp-p+n > len)
1743     {
1744       xfree (buf);
1745       return gpg_error (GPG_ERR_INV_SEXP); /* Oops: Inconsistent S-Exp. */
1746     }
1747   
1748   memmove (buf, endp, n);
1749
1750   *r_buflen = n;
1751   *r_buf = buf;
1752   return 0;
1753 }
1754
1755
1756 \f
1757 /* Retrieve a key encryption key from the agent.  With FOREXPORT true
1758    the key shall be used for export, with false for import.  On success
1759    the new key is stored at R_KEY and its length at R_KEKLEN.  */
1760 gpg_error_t
1761 agent_keywrap_key (ctrl_t ctrl, int forexport, void **r_kek, size_t *r_keklen)
1762 {
1763   gpg_error_t err;
1764   membuf_t data;
1765   size_t len;
1766   unsigned char *buf;
1767   char line[ASSUAN_LINELENGTH];
1768
1769   *r_kek = NULL;
1770   err = start_agent (ctrl, 0);
1771   if (err)
1772     return err;
1773
1774   snprintf (line, DIM(line)-1, "KEYWRAP_KEY %s",
1775             forexport? "--export":"--import");
1776
1777   init_membuf_secure (&data, 64);
1778   err = assuan_transact (agent_ctx, line,
1779                          membuf_data_cb, &data, 
1780                          default_inq_cb, ctrl, NULL, NULL);
1781   if (err)
1782     {
1783       xfree (get_membuf (&data, &len));
1784       return err;
1785     }
1786   buf = get_membuf (&data, &len);
1787   if (!buf)
1788     return gpg_error_from_syserror ();
1789   *r_kek = buf;
1790   *r_keklen = len;
1791   return 0;
1792 }
1793
1794
1795 \f
1796 /* Handle the inquiry for an IMPORT_KEY command.  */
1797 static gpg_error_t
1798 inq_import_key_parms (void *opaque, const char *line)
1799 {
1800   struct import_key_parm_s *parm = opaque; 
1801   gpg_error_t err;
1802
1803   if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
1804     {
1805       err = assuan_send_data (parm->ctx, parm->key, parm->keylen);
1806     }
1807   else
1808     err = default_inq_cb (parm->ctrl, line);
1809
1810   return err; 
1811 }
1812
1813
1814 /* Call the agent to import a key into the agent.  */
1815 gpg_error_t
1816 agent_import_key (ctrl_t ctrl, const char *desc, char **cache_nonce_addr,
1817                   const void *key, size_t keylen)
1818 {
1819   gpg_error_t err;
1820   struct import_key_parm_s parm;
1821   char line[ASSUAN_LINELENGTH];
1822
1823   err = start_agent (ctrl, 0);
1824   if (err)
1825     return err;
1826
1827   if (desc)
1828     {
1829       snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
1830       line[DIM(line)-1] = 0;
1831       err = assuan_transact (agent_ctx, line,
1832                             NULL, NULL, NULL, NULL, NULL, NULL);
1833       if (err)
1834         return err;
1835     }
1836
1837   parm.ctrl   = ctrl;
1838   parm.ctx    = agent_ctx;
1839   parm.key    = key;
1840   parm.keylen = keylen;
1841
1842   snprintf (line, sizeof line, "IMPORT_KEY%s%s",
1843             cache_nonce_addr && *cache_nonce_addr? " ":"",
1844             cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"");
1845   err = assuan_transact (agent_ctx, line,
1846                          NULL, NULL, inq_import_key_parms, &parm,
1847                          cache_nonce_status_cb, cache_nonce_addr);
1848   return err;
1849 }
1850
1851