Generating an OpenPGP key cia gpg-agent basically works.
[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 with the given keygrip is
1298    known.  */
1299 gpg_error_t
1300 agent_havekey (ctrl_t ctrl, const char *hexkeygrip)
1301 {
1302   gpg_error_t err;
1303   char line[ASSUAN_LINELENGTH];
1304
1305   err = start_agent (ctrl, 0);
1306   if (err)
1307     return err;
1308
1309   if (!hexkeygrip || strlen (hexkeygrip) != 40)
1310     return gpg_error (GPG_ERR_INV_VALUE);
1311
1312   snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip);
1313   line[DIM(line)-1] = 0;
1314
1315   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1316   return err;
1317 }
1318
1319
1320 \f
1321 static gpg_error_t
1322 keyinfo_status_cb (void *opaque, const char *line)
1323 {
1324   char **serialno = opaque;
1325   const char *s, *s2;
1326
1327   if (!strncmp (line, "KEYINFO ", 8) && !*serialno)
1328     {
1329       s = strchr (line+8, ' ');
1330       if (s && s[1] == 'T' && s[2] == ' ' && s[3])
1331         {
1332           s += 3;
1333           s2 = strchr (s, ' ');
1334           if ( s2 > s )
1335             {
1336               *serialno = xtrymalloc ((s2 - s)+1);
1337               if (*serialno)
1338                 {
1339                   memcpy (*serialno, s, s2 - s);
1340                   (*serialno)[s2 - s] = 0;
1341                 }
1342             }
1343         }
1344     }
1345   return 0;
1346 }
1347
1348
1349 /* Return the serial number for a secret key.  If the returned serial
1350    number is NULL, the key is not stored on a smartcard.  Caller needs
1351    to free R_SERIALNO.  */
1352 gpg_error_t
1353 agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
1354 {
1355   gpg_error_t err;
1356   char line[ASSUAN_LINELENGTH];
1357   char *serialno = NULL;
1358
1359   *r_serialno = NULL;
1360
1361   err = start_agent (ctrl, 0);
1362   if (err)
1363     return err;
1364
1365   if (!hexkeygrip || strlen (hexkeygrip) != 40)
1366     return gpg_error (GPG_ERR_INV_VALUE);
1367
1368   snprintf (line, DIM(line)-1, "KEYINFO %s", hexkeygrip);
1369   line[DIM(line)-1] = 0;
1370
1371   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
1372                          keyinfo_status_cb, &serialno);
1373   if (!err && serialno)
1374     {
1375       /* Sanity check for bad characters.  */
1376       if (strpbrk (serialno, ":\n\r"))
1377         err = GPG_ERR_INV_VALUE;
1378     }
1379   if (err)
1380     xfree (serialno);
1381   else
1382     *r_serialno = serialno;
1383   return err;
1384 }
1385
1386
1387 \f
1388 /* Handle a KEYPARMS inquiry.  Note, we only send the data,
1389    assuan_transact takes care of flushing and writing the end */
1390 static gpg_error_t
1391 inq_genkey_parms (void *opaque, const char *line)
1392 {
1393   struct genkey_parm_s *parm = opaque; 
1394   gpg_error_t err;
1395
1396   if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
1397     {
1398       err = assuan_send_data (parm->ctx,
1399                               parm->keyparms, strlen (parm->keyparms));
1400     }
1401   else
1402     err = default_inq_cb (parm->ctrl, line);
1403
1404   return err; 
1405 }
1406
1407
1408 /* Call the agent to generate a new key.  KEYPARMS is the usual
1409    S-expression giving the parameters of the key.  gpg-agent passes it
1410    gcry_pk_genkey.  */
1411 gpg_error_t
1412 agent_genkey (ctrl_t ctrl, const char *keyparms, gcry_sexp_t *r_pubkey)
1413 {
1414   gpg_error_t err;
1415   struct genkey_parm_s gk_parm;
1416   membuf_t data;
1417   size_t len;
1418   unsigned char *buf;
1419
1420   *r_pubkey = NULL;
1421   err = start_agent (ctrl, 0);
1422   if (err)
1423     return err;
1424
1425   err = assuan_transact (agent_ctx, "RESET", 
1426                          NULL, NULL, NULL, NULL, NULL, NULL);
1427   if (err)
1428     return err;
1429
1430   init_membuf (&data, 1024);
1431   gk_parm.ctrl     = ctrl;
1432   gk_parm.ctx      = agent_ctx;
1433   gk_parm.keyparms = keyparms;
1434   err = assuan_transact (agent_ctx, "GENKEY",
1435                          membuf_data_cb, &data, 
1436                          inq_genkey_parms, &gk_parm, NULL, NULL);
1437   if (err)
1438     {
1439       xfree (get_membuf (&data, &len));
1440       return err;
1441     }
1442   
1443   buf = get_membuf (&data, &len);
1444   if (!buf)
1445     err = gpg_error_from_syserror ();
1446   else
1447     {
1448       err = gcry_sexp_sscan (r_pubkey, NULL, buf, len);
1449       xfree (buf);
1450     }
1451   return err;
1452 }
1453
1454
1455
1456 \f
1457 /* FIXME: Call the agent to read the public key part for a given keygrip.  If
1458    FROMCARD is true, the key is directly read from the current
1459    smartcard. In this case HEXKEYGRIP should be the keyID
1460    (e.g. OPENPGP.3). */
1461 /* int */
1462 /* agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, */
1463 /*                ksba_sexp_t *r_pubkey) */
1464 /* { */
1465 /*   int rc; */
1466 /*   membuf_t data; */
1467 /*   size_t len; */
1468 /*   unsigned char *buf; */
1469 /*   char line[ASSUAN_LINELENGTH]; */
1470
1471 /*   *r_pubkey = NULL; */
1472 /*   rc = start_agent (ctrl); */
1473 /*   if (rc) */
1474 /*     return rc; */
1475
1476 /*   rc = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL); */
1477 /*   if (rc) */
1478 /*     return rc; */
1479
1480 /*   snprintf (line, DIM(line)-1, "%sREADKEY %s", */
1481 /*             fromcard? "SCD ":"", hexkeygrip); */
1482 /*   line[DIM(line)-1] = 0; */
1483
1484 /*   init_membuf (&data, 1024); */
1485 /*   rc = assuan_transact (agent_ctx, line, */
1486 /*                         membuf_data_cb, &data,  */
1487 /*                         default_inq_cb, ctrl, NULL, NULL); */
1488 /*   if (rc) */
1489 /*     { */
1490 /*       xfree (get_membuf (&data, &len)); */
1491 /*       return rc; */
1492 /*     } */
1493 /*   buf = get_membuf (&data, &len); */
1494 /*   if (!buf) */
1495 /*     return gpg_error (GPG_ERR_ENOMEM); */
1496 /*   if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) */
1497 /*     { */
1498 /*       xfree (buf); */
1499 /*       return gpg_error (GPG_ERR_INV_SEXP); */
1500 /*     } */
1501 /*   *r_pubkey = buf; */
1502 /*   return 0; */
1503 /* } */
1504
1505
1506 \f
1507 /* Call the agent to do a sign operation using the key identified by
1508    the hex string KEYGRIP.  DESC is a description of the key to be
1509    displayed if the agent needs to ask for the PIN.  DIGEST and
1510    DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
1511    used to compute the digest.  */
1512 gpg_error_t
1513 agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
1514               unsigned char *digest, size_t digestlen, int digestalgo,
1515               gcry_sexp_t *r_sigval)
1516 {
1517   gpg_error_t err;
1518   int i;
1519   char *p, line[ASSUAN_LINELENGTH];
1520   membuf_t data;
1521
1522   *r_sigval = NULL;
1523   err = start_agent (ctrl, 0);
1524   if (err)
1525     return err;
1526
1527   if (digestlen*2 + 50 > DIM(line))
1528     return gpg_error (GPG_ERR_GENERAL);
1529
1530   err = assuan_transact (agent_ctx, "RESET",
1531                          NULL, NULL, NULL, NULL, NULL, NULL);
1532   if (err)
1533     return err;
1534
1535   snprintf (line, DIM(line)-1, "SIGKEY %s", keygrip);
1536   line[DIM(line)-1] = 0;
1537   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1538   if (err)
1539     return err;
1540
1541   if (desc)
1542     {
1543       snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
1544       line[DIM(line)-1] = 0;
1545       err = assuan_transact (agent_ctx, line,
1546                             NULL, NULL, NULL, NULL, NULL, NULL);
1547       if (err)
1548         return err;
1549     }
1550
1551   snprintf (line, sizeof line, "SETHASH %d ", digestalgo);
1552   p = line + strlen (line);
1553   for (i=0; i < digestlen ; i++, p += 2 )
1554     sprintf (p, "%02X", digest[i]);
1555   err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
1556   if (err)
1557     return err;
1558
1559   init_membuf (&data, 1024);
1560   err = assuan_transact (agent_ctx, "PKSIGN",
1561                         membuf_data_cb, &data, default_inq_cb, ctrl,
1562                         NULL, NULL);
1563   if (err)
1564     xfree (get_membuf (&data, NULL));
1565   else
1566     {
1567       unsigned char *buf;
1568       size_t len;
1569
1570       buf = get_membuf (&data, &len);
1571       if (!buf)
1572         err = gpg_error_from_syserror ();
1573       else
1574         {
1575           err = gcry_sexp_sscan (r_sigval, NULL, buf, len);
1576           xfree (buf);
1577         }
1578     }
1579   return err;
1580 }
1581
1582