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