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