(parse_signature): Use log_info for messages
[gnupg.git] / g10 / cardglue.c
1 /* cardglue.c - mainly dispatcher for card related functions.
2  * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19  * USA.
20  */
21
22 #include <config.h>
23 #ifndef ENABLE_CARD_SUPPORT
24 #error  not configured for card support.
25 #endif
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <stdarg.h>
31 #include <assert.h>
32
33 #include "options.h"
34 #include "packet.h"
35 #include "errors.h"
36 #include "memory.h"
37 #include "util.h"
38 #include "main.h"
39 #include "status.h"
40 #include "ttyio.h"
41 #include "i18n.h"
42
43 #include "cardglue.h"
44 #include "apdu.h"
45 #include "app-common.h"
46
47
48
49 struct ctrl_ctx_s 
50 {
51   assuan_error_t (*status_cb)(void *opaque, const char *line);
52   void *status_cb_arg;
53 };
54
55
56 struct pincb_parm_s
57 {
58   const char *sn;
59 };
60
61
62 struct writekey_parm_s
63 {
64   assuan_context_t ctx;
65   const unsigned char *keydata;
66   size_t keydatalen;
67 };
68
69
70
71 static char *default_reader_port;
72 static app_t current_app;
73
74
75 /* Local prototypes. */
76 static assuan_error_t learn_status_cb (void *opaque, const char *line);
77
78
79 /* To avoid cluttering the code with bunches of ifdefs we use a few
80    dummy functions instead and defines. */
81 #ifndef ENABLE_AGENT_SUPPORT
82
83 #define ASSUAN_LINELENGTH 100
84
85 static assuan_context_t 
86 agent_open (int try)
87 {
88   return NULL;
89 }
90
91 void 
92 agent_close (assuan_context_t ctx)
93 {
94 }
95
96 const char *
97 assuan_strerror (assuan_error_t err)
98 {
99   return "no Assuan support";
100 }
101
102 assuan_error_t 
103 assuan_transact (assuan_context_t ctx,
104                  const char *command,
105                  assuan_error_t (*data_cb)(void *, const void *, size_t),
106                  void *data_cb_arg,
107                  assuan_error_t (*inquire_cb)(void*, const char *),
108                  void *inquire_cb_arg,
109                  assuan_error_t (*status_cb)(void*, const char *),
110                  void *status_cb_arg)
111 {
112   return 100; /* ASSUAN_NOT_IMPLEMENTED */
113 }
114 assuan_error_t 
115 assuan_send_data (assuan_context_t ctx, const void *buffer, size_t length)
116 {
117   return 100; /* ASSUAN_NOT_IMPLEMENTED */
118 }  
119 #endif /*!ENABLE_AGENT_SUPPORT*/
120
121 \f
122 /* Create a serialno/fpr string from the serial number and the secret
123    key.  caller must free the returned string.  There is no error
124    return. [Taken from 1.9's keyid.c]*/
125 char *
126 serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
127                           PKT_secret_key *sk)
128 {
129   unsigned char fpr[MAX_FINGERPRINT_LEN];
130   size_t fprlen;
131   char *buffer, *p;
132   int i;
133   
134   fingerprint_from_sk (sk, fpr, &fprlen);
135   buffer = p = xmalloc (snlen*2 + 1 + fprlen*2 + 1);
136   for (i=0; i < snlen; i++, p+=2)
137     sprintf (p, "%02X", sn[i]);
138   *p++ = '/';
139   for (i=0; i < fprlen; i++, p+=2)
140     sprintf (p, "%02X", fpr[i]);
141   *p = 0;
142   return buffer;
143 }
144
145
146 /* Send a line with status information via assuan and escape all given
147    buffers. The variable elements are pairs of (char *, size_t),
148    terminated with a (NULL, 0). */
149 void
150 send_status_info (ctrl_t ctrl, const char *keyword, ...)
151 {
152   va_list arg_ptr;
153   const unsigned char *value;
154   size_t valuelen;
155   char buf[950], *p;
156   size_t n;
157   
158   va_start (arg_ptr, keyword);
159
160   p = buf; 
161   n = 0;
162   valuelen = strlen (keyword);
163   for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, keyword++)
164     *p++ = *keyword;
165
166   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
167     {
168       valuelen = va_arg (arg_ptr, size_t);
169       if (!valuelen)
170         continue; /* empty buffer */
171       if (n)
172         {
173           *p++ = ' ';
174           n++;
175         }
176       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
177         {
178           if (*value < ' ' || *value == '+')
179             {
180               sprintf (p, "%%%02X", *value);
181               p += 3;
182             }
183           else if (*value == ' ')
184             *p++ = '+';
185           else
186             *p++ = *value;
187         }
188     }
189   *p = 0;
190   if (ctrl && ctrl->status_cb)
191     ctrl->status_cb (ctrl->status_cb_arg, buf);
192
193   va_end (arg_ptr);
194 }
195
196
197 /* Replacement function of the Libgcrypt onewhich is used in gnupg
198    1.9.  Thus function computes the digest of ALGO from the data in
199    BUFFER of LENGTH.  ALGO must be supported. */
200 void 
201 gcry_md_hash_buffer (int algo, void *digest,
202                      const void *buffer, size_t length)
203 {
204   MD_HANDLE h = md_open (algo, 0);
205   if (!h)
206     BUG();
207   md_write (h, (byte *) buffer, length);
208   md_final (h);
209   memcpy (digest, md_read (h, algo), md_digest_length (algo));
210   md_close (h);
211 }
212
213
214 /* This is a limited version of the one in 1.9 but it should be
215    sufficient here. */
216 void
217 log_printf (const char *fmt, ...)
218 {
219   va_list arg_ptr;
220
221   va_start (arg_ptr, fmt);
222   vfprintf (log_stream (), fmt, arg_ptr);
223   va_end (arg_ptr);
224 }
225
226
227
228 /* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
229    dump, with TEXT just an empty string, print a trailing linefeed,
230    otherwise print an entire debug line. */
231 void
232 log_printhex (const char *text, const void *buffer, size_t length)
233 {
234   if (text && *text)
235     log_debug ("%s ", text);
236   if (length)
237     {
238       const unsigned char *p = buffer;
239       log_printf ("%02X", *p);
240       for (length--, p++; length--; p++)
241         log_printf (" %02X", *p);
242     }
243   if (text)
244     log_printf ("\n");
245 }
246
247
248
249 void
250 app_set_default_reader_port (const char *portstr)
251 {
252   xfree (default_reader_port);
253   default_reader_port = portstr? xstrdup (portstr): NULL;
254 }
255
256
257 void
258 card_set_reader_port (const char *portstr)
259 {
260   app_set_default_reader_port (portstr);
261 }
262
263
264 /* Retrieve the serial number and the time of the last update of the
265    card.  The serial number is returned as a malloced string (hex
266    encoded) in SERIAL and the time of update is returned in STAMP.  If
267    no update time is available the returned value is 0.  Caller must
268    free SERIAL unless the function returns an error. */
269 int 
270 app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp)
271 {
272   unsigned char *buf, *p;
273   int i;
274
275   if (!app || !serial || !stamp)
276     return gpg_error (GPG_ERR_INV_VALUE);
277
278   *serial = NULL;
279   *stamp = 0; /* not available */
280
281   buf = xtrymalloc (app->serialnolen * 2 + 1);
282   if (!buf)
283     return gpg_error_from_errno (errno);
284   for (p=buf, i=0; i < app->serialnolen; p +=2, i++)
285     sprintf (p, "%02X", app->serialno[i]);
286   *p = 0;
287   *serial = buf;
288   return 0;
289 }
290
291
292
293 /* Release the card info structure. */
294 void 
295 agent_release_card_info (struct agent_card_info_s *info)
296 {
297   int i;
298
299   if (!info)
300     return;
301
302   xfree (info->serialno); info->serialno = NULL;
303   xfree (info->disp_name); info->disp_name = NULL;
304   xfree (info->disp_lang); info->disp_lang = NULL;
305   xfree (info->pubkey_url); info->pubkey_url = NULL;
306   xfree (info->login_data); info->login_data = NULL;
307   info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
308   info->cafpr1valid = info->cafpr2valid = info->cafpr3valid = 0;
309   for (i=0; i < 4; i++)
310     {
311       xfree (info->private_do[i]);
312       info->private_do[i] = NULL;
313     }
314 }
315
316
317 /* Print an error message for a failed assuan_transact and return a
318    gpg error code. No error is printed if RC is 0. */
319 static gpg_error_t
320 test_transact (int rc, const char *command)
321 {
322   if (!rc)
323     return 0;
324   log_error ("sending command `%s' to agent failed: %s\n",
325              command, assuan_strerror (rc));
326   return gpg_error (GPG_ERR_CARD);
327 }
328
329
330 /* Try to open a card using an already running agent.  Prepare a
331    proper application context and return it. */
332 static app_t
333 open_card_via_agent (int *scd_available)
334 {
335   assuan_context_t ctx;
336   app_t app;
337   struct agent_card_info_s info;
338   int rc;
339
340   *scd_available = 0;
341   ctx = agent_open (1);
342   if (!ctx)
343     return NULL;
344
345   /* Request the serialbnumber of the card.  If we get
346      NOT_SUPPORTED or NO_SCDAEMON back, the gpg-agent either has
347      disabled scdaemon or it can't be used.  We close the connection
348      in this case and use our own code.  This may happen if just the
349      gpg-agent has been installed for the sake of passphrase
350      caching. */
351   memset (&info, 0, sizeof info);
352   rc = assuan_transact (ctx, "SCD SERIALNO openpgp",
353                         NULL, NULL, NULL, NULL,
354                         learn_status_cb, &info);
355   if (rc)
356     {
357       if ((rc & 0xffff) == 60 || (rc & 0xffff) == 119)
358         ;  /* No scdaemon available to gpg-agent. */
359       else
360         {
361           write_status_text (STATUS_CARDCTRL, "4");
362           log_info ("selecting openpgp failed: %s\n", assuan_strerror (rc));
363           *scd_available = 1;
364         }
365       agent_release_card_info (&info);
366       agent_close (ctx);
367       return NULL;
368     }
369   
370   app = xcalloc (1, sizeof *app);
371   app->assuan_ctx = ctx;
372
373   return app;
374 }
375
376
377
378 /* Open the current card and select the openpgp application.  Return
379    an APP context handle to be used for further procesing or NULL on
380    error or if no OpenPGP application exists.*/
381 static app_t
382 open_card (void)
383 {
384   int slot = -1;
385   int rc;
386   app_t app;
387   int did_shutdown = 0;
388
389   /* First check whether we can contact a gpg-agent and divert all
390      operation to it. This is required because gpg as well as the
391      agent require exclusive access to the reader. */
392   if (opt.use_agent)
393     {
394       int scd_available;
395
396       app = open_card_via_agent (&scd_available);
397       if (app)
398         goto ready; /* Yes, there is a agent with a usable card, go that way. */
399       if (scd_available)
400         return NULL; /* agent avilabale but card problem. */
401     }
402
403
404   /* No agent or usable agent, thus we do it on our own. */
405   card_close ();
406   
407  retry:
408   if (did_shutdown)
409     apdu_reset (slot);
410   else
411     {
412       slot = apdu_open_reader (default_reader_port);
413       if (slot == -1)
414         {
415           write_status_text (STATUS_CARDCTRL, "5");
416           log_error ("card reader not available\n");
417           return NULL;
418         }
419     }
420
421   app = xcalloc (1, sizeof *app);
422   app->slot = slot;
423   rc = app_select_openpgp (app);
424   if (rc && !opt.batch)
425     {
426       write_status_text (STATUS_CARDCTRL, "1");
427       
428       did_shutdown = !!apdu_shutdown_reader (slot);
429
430       if ( cpr_get_answer_okay_cancel ("cardctrl.insert_card.okay",
431            _("Please insert the card and hit return or enter 'c' to cancel: "),
432                                        1) )
433         {
434           if (!did_shutdown)
435             apdu_close_reader (slot);
436           xfree (app);
437           goto retry;
438         }
439     }
440   if (rc)
441     {
442       write_status_text (STATUS_CARDCTRL, "4");
443       log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
444       apdu_close_reader (slot);
445       xfree (app);
446       return NULL;
447     }
448
449  ready:
450   app->initialized = 1;
451   current_app = app;
452   if (is_status_enabled () )
453     {
454       int i;
455       char *p, *buf;
456
457       buf = xmalloc (5 + app->serialnolen * 2 + 1);
458       p = stpcpy (buf, "3 ");
459       for (i=0; i < app->serialnolen; p +=2, i++)
460         sprintf (p, "%02X", app->serialno[i]);
461       write_status_text (STATUS_CARDCTRL, buf);
462       xfree (buf);
463     }
464
465   return app;
466 }
467
468
469 void
470 card_close (void)
471 {
472   if (current_app)
473     {
474       app_t app = current_app;
475       current_app = NULL;
476
477       if (app->assuan_ctx)
478         agent_close (app->assuan_ctx);
479       else
480         apdu_close_reader (app->slot);
481       xfree (app);
482     }
483 }
484
485
486 /* Format a cache ID from the serialnumber in SN and return it as an
487    allocated string.  In case of an error NULL is returned. */
488 static char *
489 format_cacheid (const char *sn)
490 {
491   const char *s;
492   size_t snlen;
493   char *cacheid = NULL;
494
495   /* The serialnumber we use for a card is "CARDSN:serialno".  Where
496      serialno is the BCD string (i.e. hex string) with the full
497      number.  The serial number expect here constsis of hexdigits
498      followed by other characters, we cut off these other
499      characters. */
500   if (sn)
501     {
502       for (s=sn,snlen=0; hexdigitp (s); s++, snlen++)
503         ;
504       if (snlen == 32)
505         {
506           /* Yes, this looks indeed like an OpenPGP card S/N. */
507           cacheid = xtrymalloc (7+snlen+1);
508           if (cacheid)
509             {
510               memcpy (cacheid, "CARDSN:", 7);
511               memcpy (cacheid+7, sn, snlen);
512               cacheid[7+snlen] = 0;
513             }
514         }
515     }
516   return cacheid;
517 }
518
519 /* Check that the serial number of the current card (as described by
520    APP) matches SERIALNO.  If there is no match and we are not in
521    batch mode, present a prompt to insert the desired card.  The
522    function return 0 is the present card is okay, -1 if the user
523    selected to insert a new card or an error value.  Note that the
524    card context will be closed in all cases except for 0 as return
525    value and if it was possible to merely shutdown the reader. */
526 static int
527 check_card_serialno (app_t app, const char *serialno)
528 {
529   const char *s;
530   int ask = 0;
531   int n;
532   
533   for (s = serialno, n=0; *s != '/' && hexdigitp (s); s++, n++)
534     ;
535   if (n != 32)
536     {
537       log_error ("invalid serial number in keyring detected\n");
538       return gpg_error (GPG_ERR_INV_ID);
539     }
540   if (app->serialnolen != 16)
541     ask = 1;
542   for (s = serialno, n=0; !ask && n < 16; s += 2, n++)
543     if (app->serialno[n] != xtoi_2 (s))
544       ask = 1;
545   if (ask)
546     {
547       char buf[5+32+1];
548       int did_shutdown = 0;
549
550       if (current_app && !apdu_shutdown_reader (current_app->slot))
551         did_shutdown = 1;
552       else
553         card_close ();
554       tty_printf (_("Please remove the current card and "
555                     "insert the one with serial number:\n"
556                     "   %.*s\n"), 32, serialno);
557
558       sprintf (buf, "1 %.32s", serialno);
559       write_status_text (STATUS_CARDCTRL, buf);
560
561       if ( cpr_get_answer_okay_cancel ("cardctrl.change_card.okay",
562                           _("Hit return when ready "
563                             "or enter 'c' to cancel: "),
564                                        1) )
565         {
566           card_close ();
567           return -1;
568         }
569       if (did_shutdown)
570         apdu_reset (current_app->slot);
571       else
572         card_close ();
573       return gpg_error (GPG_ERR_INV_ID);
574     }
575   return 0;
576 }
577
578
579 /* Take a 20 byte hexencoded string and put it into the the provided
580    20 byte buffer FPR in binary format. */
581 static int
582 unhexify_fpr (const char *hexstr, unsigned char *fpr)
583 {
584   const char *s;
585   int n;
586
587   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
588     ;
589   if (*s || (n != 40))
590     return 0; /* no fingerprint (invalid or wrong length). */
591   n /= 2;
592   for (s=hexstr, n=0; *s; s += 2, n++)
593     fpr[n] = xtoi_2 (s);
594   return 1; /* okay */
595 }
596
597 /* Take the serial number from LINE and return it verbatim in a newly
598    allocated string.  We make sure that only hex characters are
599    returned. */
600 static char *
601 store_serialno (const char *line)
602 {
603   const char *s;
604   char *p;
605
606   for (s=line; hexdigitp (s); s++)
607     ;
608   p = xmalloc (s + 1 - line);
609   memcpy (p, line, s-line);
610   p[s-line] = 0;
611   return p;
612 }
613
614
615
616 static assuan_error_t
617 learn_status_cb (void *opaque, const char *line)
618 {
619   struct agent_card_info_s *parm = opaque;
620   const char *keyword = line;
621   int keywordlen;
622   int i;
623
624 /*   log_debug ("got status line `%s'\n", line); */
625   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
626     ;
627   while (spacep (line))
628     line++;
629
630   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
631     {
632       xfree (parm->serialno);
633       parm->serialno = store_serialno (line);
634     }
635   else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
636     {
637       xfree (parm->disp_name);
638       parm->disp_name = unescape_percent_string (line);
639     }
640   else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
641     {
642       xfree (parm->disp_lang);
643       parm->disp_lang = unescape_percent_string (line);
644     }
645   else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
646     {
647       parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
648     }
649   else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
650     {
651       xfree (parm->pubkey_url);
652       parm->pubkey_url = unescape_percent_string (line);
653     }
654   else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
655     {
656       xfree (parm->login_data);
657       parm->login_data = unescape_percent_string (line);
658     }
659   else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
660     {
661       parm->sig_counter = strtoul (line, NULL, 0);
662     }
663   else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
664     {
665       char *p, *buf;
666
667       buf = p = unescape_percent_string (line);
668       if (buf)
669         {
670           while (spacep (p))
671             p++;
672           parm->chv1_cached = atoi (p);
673           while (*p && !spacep (p))
674             p++;
675           while (spacep (p))
676             p++;
677           for (i=0; *p && i < 3; i++)
678             {
679               parm->chvmaxlen[i] = atoi (p);
680               while (*p && !spacep (p))
681                 p++;
682               while (spacep (p))
683                 p++;
684             }
685           for (i=0; *p && i < 3; i++)
686             {
687               parm->chvretry[i] = atoi (p);
688               while (*p && !spacep (p))
689                 p++;
690               while (spacep (p))
691                 p++;
692             }
693           xfree (buf);
694         }
695     }
696   else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
697     {
698       int no = atoi (line);
699       while (* line && !spacep (line))
700         line++;
701       while (spacep (line))
702         line++;
703       if (no == 1)
704         parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
705       else if (no == 2)
706         parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
707       else if (no == 3)
708         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
709     }
710   else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
711     {
712       int no = atoi (line);
713       while (* line && !spacep (line))
714         line++;
715       while (spacep (line))
716         line++;
717       if (no == 1)
718         parm->fpr1time = strtoul (line, NULL, 10);
719       else if (no == 2)
720         parm->fpr2time = strtoul (line, NULL, 10);
721       else if (no == 3)
722         parm->fpr3time = strtoul (line, NULL, 10);
723     }
724   else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
725     {
726       int no = atoi (line);
727       while (*line && !spacep (line))
728         line++;
729       while (spacep (line))
730         line++;
731       if (no == 1)
732         parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
733       else if (no == 2)
734         parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
735       else if (no == 3)
736         parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
737     }
738   else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
739            && strchr ("1234", keyword[11]))
740     {
741       int no = keyword[11] - '1';
742       assert (no >= 0 && no <= 3);
743       xfree (parm->private_do[no]);
744       parm->private_do[no] = unescape_percent_string (line);
745     }
746  
747   return 0;
748 }
749
750
751 /* Return card info. */
752 int 
753 agent_learn (struct agent_card_info_s *info)
754 {
755   app_t app;
756   int rc;
757   struct ctrl_ctx_s ctrl;
758   time_t stamp;
759   char *serial;
760   
761   app = current_app? current_app : open_card ();
762   if (!app)
763     return gpg_error (GPG_ERR_CARD);
764
765   memset (info, 0, sizeof *info);
766
767   if (app->assuan_ctx)
768     {
769       rc = assuan_transact (app->assuan_ctx, "SCD LEARN --force",
770                             NULL, NULL, NULL, NULL,
771                             learn_status_cb, info);
772       rc = test_transact (rc, "SCD LEARN");
773     }
774   else
775     {
776       memset (&ctrl, 0, sizeof ctrl);
777       ctrl.status_cb = learn_status_cb;
778       ctrl.status_cb_arg = info;
779
780       rc = app_get_serial_and_stamp (app, &serial, &stamp);
781       if (!rc)
782         {
783           send_status_info (&ctrl, "SERIALNO",
784                             serial, strlen(serial), NULL, 0);
785           xfree (serial);
786           rc = app->fnc.learn_status (app, &ctrl);
787         }
788     }
789
790   return rc;
791 }
792
793
794 /* Get an attribute from the card. Make sure info is initialized. */
795 int 
796 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
797 {
798   int rc;
799   app_t app;
800   struct ctrl_ctx_s ctrl;
801
802   app = current_app? current_app : open_card ();
803   if (!app)
804     return gpg_error (GPG_ERR_CARD);
805
806   if (app->assuan_ctx)
807     {
808       char line[ASSUAN_LINELENGTH];
809
810       /* We assume that NAME does not need escaping. */
811       if (12 + strlen (name) > DIM(line)-1)
812         return gpg_error (GPG_ERR_CARD);
813       stpcpy (stpcpy (line, "SCD GETATTR "), name); 
814
815       rc = test_transact (assuan_transact (app->assuan_ctx, line,
816                                            NULL, NULL, NULL, NULL,
817                                            learn_status_cb, info),
818                           "SCD GETATTR");
819     }
820   else
821     {
822       ctrl.status_cb = learn_status_cb;
823       ctrl.status_cb_arg = info;
824       rc = app->fnc.getattr (app, &ctrl, name);
825     }
826
827   return rc;
828 }
829
830
831
832 static int 
833 pin_cb (void *opaque, const char *info, char **retstr)
834 {
835   struct pincb_parm_s *parm = opaque;
836   char *value;
837   int canceled;
838   int isadmin = 0;
839   int newpin = 0;
840   const char *again_text = NULL;
841   const char *ends, *s;
842   char *cacheid = NULL;
843
844   *retstr = NULL;
845   /*   log_debug ("asking for PIN '%s'\n", info); */
846
847   /* We use a special prefix to check whether the Admin PIN has been
848      requested. */
849   if (info && *info =='|' && (ends=strchr (info+1, '|')))
850     {
851       for (s=info+1; s < ends; s++)
852         {
853           if (*s == 'A')
854             isadmin = 1;
855           else if (*s == 'N')
856             newpin = 1;
857         }
858       info = ends+1;
859     }
860   else if (info && *info == '|')
861     log_debug ("pin_cb called without proper PIN info hack\n");
862
863   /* If we are not requesting a new PIN and we are not requesting an
864      AdminPIN, compute a string to be used as the cacheID for
865      gpg-agent. */
866   if (!newpin && !isadmin && parm)
867     {
868       cacheid = format_cacheid (parm->sn);
869     }
870   else if (newpin && parm)
871     {
872       /* Make really sure that it is not cached anymore. */
873       agent_clear_pin_cache (parm->sn);
874     }
875
876
877  again:
878   if (is_status_enabled())
879     write_status_text (STATUS_NEED_PASSPHRASE_PIN,
880                        isadmin? "OPENPGP 3" : "OPENPGP 1");
881
882   value = ask_passphrase (info, again_text,
883                           newpin && isadmin? "passphrase.adminpin.new.ask" :
884                           newpin?  "passphrase.pin.new.ask" :
885                           isadmin? "passphrase.adminpin.ask" :
886                                    "passphrase.pin.ask", 
887                           newpin && isadmin? _("Enter New Admin PIN: ") :
888                           newpin?  _("Enter New PIN: ") :
889                           isadmin? _("Enter Admin PIN: ")
890                                  : _("Enter PIN: "),
891                           cacheid,
892                           &canceled);
893   xfree (cacheid);
894   cacheid = NULL;
895   again_text = NULL;
896   if (!value && canceled)
897     return -1;
898   else if (!value)
899     return G10ERR_GENERAL;
900
901   if (newpin)
902     {
903       char *value2;
904
905       value2 = ask_passphrase (info, NULL, NULL,
906                                "passphrase.pin.repeat", 
907                                _("Repeat this PIN: "),
908                               &canceled);
909       if (!value && canceled)
910         {
911           xfree (value);
912           return -1;
913         }
914       else if (!value)
915         {
916           xfree (value);
917           return G10ERR_GENERAL;
918         }
919       if (strcmp (value, value2))
920         {
921           again_text = N_("PIN not correctly repeated; try again");
922           xfree (value2);
923           xfree (value);
924           value = NULL;
925           goto again;
926         }
927       xfree (value2);
928     }
929
930   *retstr = value;
931   return 0;
932 }
933
934
935
936 /* Send a SETATTR command to the SCdaemon. */
937 int 
938 agent_scd_setattr (const char *name,
939                    const unsigned char *value, size_t valuelen)
940 {
941   app_t app;
942   int rc;
943
944   app = current_app? current_app : open_card ();
945   if (!app)
946     return gpg_error (GPG_ERR_CARD);
947
948   if (app->assuan_ctx)
949     {
950       char line[ASSUAN_LINELENGTH];
951       char *p;
952
953       /* We assume that NAME does not need escaping. */
954       if (12 + strlen (name) > DIM(line)-1)
955         return gpg_error (GPG_ERR_CARD);
956       p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
957       *p++ = ' ';
958       for (; valuelen; value++, valuelen--)
959         {
960           if (p >= line + DIM(line)-5 )
961             return gpg_error (GPG_ERR_CARD);
962           if (*value < ' ' || *value == '+' || *value == '%')
963             {
964               sprintf (p, "%%%02X", *value);
965               p += 3;
966             }
967           else if (*value == ' ')
968             *p++ = '+';
969           else
970             *p++ = *value;
971         }
972       *p = 0;
973
974       rc = test_transact (assuan_transact (app->assuan_ctx, line,
975                                            NULL, NULL, NULL, NULL, NULL, NULL),
976                           "SCD SETATTR");
977     }
978   else
979     {
980       rc = app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen);
981     }
982
983   if (rc)
984     write_status (STATUS_SC_OP_FAILURE);
985   return rc;
986 }
987
988
989 /* Handle a KEYDATA inquiry.  Note, we only send the data,
990    assuan_transact takes care of flushing and writing the end */
991 static assuan_error_t
992 inq_writekey_parms (void *opaque, const char *keyword)
993 {
994   struct writekey_parm_s *parm = opaque; 
995
996   return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
997 }
998
999
1000 /* Send a WRITEKEY command to the SCdaemon. */
1001 int 
1002 agent_scd_writekey (int keyno, const unsigned char *keydata, size_t keydatalen)
1003 {
1004   app_t app;
1005   int rc;
1006   char line[ASSUAN_LINELENGTH];
1007   app = current_app? current_app : open_card ();
1008   if (!app)
1009     return gpg_error (GPG_ERR_CARD);
1010
1011   if (app->assuan_ctx)
1012     {
1013       struct writekey_parm_s parms;
1014
1015       snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
1016       line[DIM(line)-1] = 0;
1017       parms.ctx = app->assuan_ctx;
1018       parms.keydata = keydata;
1019       parms.keydatalen = keydatalen;
1020       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1021                                            NULL, NULL,
1022                                            inq_writekey_parms, &parms,
1023                                            NULL, NULL),
1024                           "SCD WRITEKEY");
1025     }
1026   else
1027     {
1028       snprintf (line, DIM(line)-1, "OPENPGP.%d", keyno);
1029       line[DIM(line)-1] = 0;
1030       rc = app->fnc.writekey (app, NULL, line, 0x0001,
1031                               pin_cb, NULL,
1032                               keydata, keydatalen);
1033     }
1034
1035   if (rc)
1036     write_status (STATUS_SC_OP_FAILURE);
1037   return rc;
1038 }
1039
1040
1041
1042 static assuan_error_t
1043 genkey_status_cb (void *opaque, const char *line)
1044 {
1045   struct agent_card_genkey_s *parm = opaque;
1046   const char *keyword = line;
1047   int keywordlen;
1048
1049 /*   log_debug ("got status line `%s'\n", line); */
1050   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1051     ;
1052   while (spacep (line))
1053     line++;
1054
1055   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
1056     {
1057       parm->fprvalid = unhexify_fpr (line, parm->fpr);
1058     }
1059   if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
1060     {
1061       MPI a;
1062       const char *name = line;
1063       char *buf;
1064
1065       while (*line && !spacep (line))
1066         line++;
1067       while (spacep (line))
1068         line++;
1069
1070       buf = xmalloc ( 2 + strlen (line) + 1);
1071       strcpy (stpcpy (buf, "0x"), line);
1072       a = mpi_alloc (300);
1073       if( mpi_fromstr (a, buf) )
1074         log_error ("error parsing received key data\n");
1075       else if (*name == 'n' && spacep (name+1))
1076         parm->n = a;
1077       else if (*name == 'e' && spacep (name+1))
1078         parm->e = a;
1079       else
1080         {
1081           log_info ("unknown parameter name in received key data\n");
1082           mpi_free (a);
1083         }
1084       xfree (buf);
1085     }
1086   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
1087     {
1088       parm->created_at = (u32)strtoul (line, NULL, 10);
1089     }
1090
1091   return 0;
1092 }
1093
1094 /* Send a GENKEY command to the SCdaemon. */
1095 int 
1096 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force)
1097 {
1098   app_t app;
1099   char line[ASSUAN_LINELENGTH];
1100   struct ctrl_ctx_s ctrl;
1101   int rc;
1102
1103   app = current_app? current_app : open_card ();
1104   if (!app)
1105     return gpg_error (GPG_ERR_CARD);
1106
1107   memset (info, 0, sizeof *info);
1108
1109   if (app->assuan_ctx)
1110     {
1111       snprintf (line, DIM(line)-1, "SCD GENKEY %s%d",
1112                 force? "--force ":"", keyno);
1113       line[DIM(line)-1] = 0;
1114       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1115                                            NULL, NULL, NULL, NULL,
1116                                            genkey_status_cb, info),
1117                           "SCD GENKEY");
1118     }
1119   else
1120     {
1121       snprintf (line, DIM(line)-1, "%d", keyno);
1122       ctrl.status_cb = genkey_status_cb;
1123       ctrl.status_cb_arg = info;
1124       rc = app->fnc.genkey (app, &ctrl, line,
1125                             force? 1:0,
1126                             pin_cb, NULL);
1127     }
1128
1129   if (rc)
1130     write_status (STATUS_SC_OP_FAILURE);
1131   return rc;
1132 }
1133
1134
1135 static assuan_error_t
1136 membuf_data_cb (void *opaque, const void *buffer, size_t length)
1137 {
1138   membuf_t *data = opaque;
1139
1140   if (buffer)
1141     put_membuf (data, buffer, length);
1142   return 0;
1143 }
1144   
1145
1146 /* Send a PKSIGN command to the SCdaemon. */
1147 int 
1148 agent_scd_pksign (const char *serialno, int hashalgo,
1149                   const unsigned char *indata, size_t indatalen,
1150                   unsigned char **r_buf, size_t *r_buflen)
1151 {
1152   struct pincb_parm_s parm;
1153   app_t app;
1154   int rc;
1155
1156   *r_buf = NULL;
1157   *r_buflen = 0;
1158   memset (&parm, 0, sizeof parm);
1159   parm.sn = serialno;
1160  retry:
1161   app = current_app? current_app : open_card ();
1162   if (!app)
1163     return gpg_error (GPG_ERR_CARD);
1164
1165   if (app->assuan_ctx)
1166     {
1167       char *p, line[ASSUAN_LINELENGTH];
1168       membuf_t data;
1169       size_t len;
1170       int i;
1171
1172       if (indatalen*2 + 50 > DIM(line))
1173         return gpg_error (GPG_ERR_GENERAL);
1174
1175       p = stpcpy (line, "SCD SETDATA ");
1176       for (i=0; i < indatalen ; i++, p += 2 )
1177         sprintf (p, "%02X", indata[i]);
1178       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1179                                            NULL, NULL, NULL, NULL, NULL, NULL),
1180                           "SCD SETDATA");
1181       if (!rc)
1182         {
1183           init_membuf (&data, 1024);
1184           snprintf (line, DIM(line)-1, "SCD PKSIGN %s", serialno);
1185           line[DIM(line)-1] = 0;
1186           rc = test_transact (assuan_transact (app->assuan_ctx, line,
1187                                                membuf_data_cb, &data,
1188                                                NULL, NULL, NULL, NULL),
1189                               "SCD PKSIGN");
1190           if (rc)
1191             xfree (get_membuf (&data, &len));
1192           else
1193             *r_buf = get_membuf (&data, r_buflen);
1194         }
1195     }
1196   else
1197     {
1198       /* Check that the card's serialnumber is as required.*/
1199       rc = check_card_serialno (app, serialno);
1200       if (rc == -1)
1201         goto retry;
1202
1203       if (!rc)
1204         rc = app->fnc.sign (app, serialno, hashalgo,
1205                             pin_cb, &parm,
1206                             indata, indatalen,
1207                             r_buf, r_buflen);
1208     }
1209
1210   if (rc)
1211     {
1212       write_status (STATUS_SC_OP_FAILURE);
1213       if (!app->assuan_ctx)
1214         agent_clear_pin_cache (serialno);
1215     }
1216   return rc;
1217 }
1218
1219
1220 /* Send a PKDECRYPT command to the SCdaemon. */
1221 int 
1222 agent_scd_pkdecrypt (const char *serialno,
1223                      const unsigned char *indata, size_t indatalen,
1224                      unsigned char **r_buf, size_t *r_buflen)
1225 {
1226   struct pincb_parm_s parm;
1227   app_t app;
1228   int rc;
1229
1230   *r_buf = NULL;
1231   *r_buflen = 0;
1232   memset (&parm, 0, sizeof parm);
1233   parm.sn = serialno;
1234  retry:
1235   app = current_app? current_app : open_card ();
1236   if (!app)
1237     return gpg_error (GPG_ERR_CARD);
1238
1239   if (app->assuan_ctx)
1240     {
1241       char *p, line[ASSUAN_LINELENGTH];
1242       membuf_t data;
1243       size_t len;
1244       int i;
1245
1246       if (indatalen*2 + 50 > DIM(line))
1247         return gpg_error (GPG_ERR_GENERAL);
1248
1249       p = stpcpy (line, "SCD SETDATA ");
1250       for (i=0; i < indatalen ; i++, p += 2 )
1251         sprintf (p, "%02X", indata[i]);
1252       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1253                                            NULL, NULL, NULL, NULL, NULL, NULL),
1254                           "SCD SETDATA");
1255       if (!rc)
1256         {
1257           init_membuf (&data, 1024);
1258           snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
1259           line[DIM(line)-1] = 0;
1260           rc = test_transact (assuan_transact (app->assuan_ctx, line,
1261                                                membuf_data_cb, &data,
1262                                                NULL, NULL, NULL, NULL),
1263                               "SCD PKDECRYPT");
1264           if (rc)
1265             xfree (get_membuf (&data, &len));
1266           else
1267             *r_buf = get_membuf (&data, r_buflen);
1268         }
1269     }
1270   else
1271     {
1272       /* Check that the card's serialnumber is as required.*/
1273       rc = check_card_serialno (app, serialno);
1274       if (rc == -1)
1275         goto retry;
1276       
1277       if (!rc)
1278         rc = app->fnc.decipher (app, serialno, 
1279                                 pin_cb, &parm,
1280                                 indata, indatalen,
1281                                 r_buf, r_buflen);
1282     }
1283
1284   if (rc)
1285     {
1286       write_status (STATUS_SC_OP_FAILURE);
1287       if (!app->assuan_ctx)
1288         agent_clear_pin_cache (serialno);
1289     }
1290   return rc;
1291 }
1292
1293 /* Change the PIN of an OpenPGP card or reset the retry counter. */
1294 int 
1295 agent_scd_change_pin (int chvno)
1296 {
1297   app_t app;
1298   int reset = 0;
1299   int rc;
1300
1301   reset = (chvno >= 100);
1302   chvno %= 100;
1303
1304   app = current_app? current_app : open_card ();
1305   if (!app)
1306     return gpg_error (GPG_ERR_CARD);
1307
1308   if (app->assuan_ctx)
1309     {
1310       char line[ASSUAN_LINELENGTH];
1311
1312       snprintf (line, DIM(line)-1, "SCD PASSWD%s %d",
1313                 reset? " --reset":"", chvno);
1314       line[DIM(line)-1] = 0;
1315       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1316                                            NULL, NULL, NULL, NULL, NULL, NULL),
1317                           "SCD PASSWD");
1318     }
1319   else
1320     {
1321       char chvnostr[50];
1322
1323       sprintf (chvnostr, "%d", chvno);
1324       rc = app->fnc.change_pin (app, NULL, chvnostr, reset,
1325                                 pin_cb, NULL);
1326     }
1327
1328   if (rc)
1329     write_status (STATUS_SC_OP_FAILURE);
1330   return rc;
1331 }
1332
1333 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
1334    number of the card - optionally followed by the fingerprint;
1335    however the fingerprint is ignored here. */
1336 int
1337 agent_scd_checkpin (const char *serialnobuf)
1338 {
1339   app_t app;
1340   int rc;
1341
1342   app = current_app? current_app : open_card ();
1343   if (!app)
1344     return gpg_error (GPG_ERR_CARD);
1345
1346   if (app->assuan_ctx)
1347     {
1348       char line[ASSUAN_LINELENGTH];
1349
1350       if (15 + strlen (serialnobuf) > DIM(line)-1)
1351         return gpg_error (GPG_ERR_CARD);
1352       stpcpy (stpcpy (line, "SCD CHECKPIN "), serialnobuf); 
1353       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1354                                            NULL, NULL, NULL, NULL, NULL, NULL),
1355                           "SCD CHECKPIN");
1356     }
1357   else
1358     {
1359       rc = app->fnc.check_pin (app, serialnobuf, pin_cb, NULL);
1360     }
1361
1362   if (rc)
1363     write_status (STATUS_SC_OP_FAILURE);
1364   return rc;
1365 }
1366
1367
1368
1369 void
1370 agent_clear_pin_cache (const char *sn)
1371 {
1372   char *cacheid = format_cacheid (sn);
1373   if (cacheid)
1374     {
1375       passphrase_clear_cache (NULL, cacheid, 0);
1376       xfree (cacheid);
1377     }
1378 }