Updated card stuff to support T=0 cards.
[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, const char *orig_codeset)
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, NULL);
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   int retry_count = 0;
389
390   /* First check whether we can contact a gpg-agent and divert all
391      operation to it. This is required because gpg as well as the
392      agent require exclusive access to the reader. */
393   if (opt.use_agent)
394     {
395       int scd_available;
396
397       app = open_card_via_agent (&scd_available);
398       if (app)
399         goto ready; /* Yes, there is a agent with a usable card, go that way. */
400       if (scd_available)
401         return NULL; /* agent avilabale but card problem. */
402     }
403
404
405   /* No agent or usable agent, thus we do it on our own. */
406   card_close ();
407   
408  retry:
409   if (did_shutdown)
410     apdu_reset (slot);
411   else
412     {
413       slot = apdu_open_reader (default_reader_port);
414       if (slot == -1)
415         {
416           write_status_text (STATUS_CARDCTRL, "5");
417           log_error ("card reader not available\n");
418           return NULL;
419         }
420     }
421
422   app = xcalloc (1, sizeof *app);
423   app->slot = slot;
424   rc = app_select_openpgp (app);
425   if (opt.limit_card_insert_tries 
426       && ++retry_count >= opt.limit_card_insert_tries)
427     ;
428   else if (rc && !opt.batch)
429     {
430       write_status_text (STATUS_CARDCTRL, "1");
431       
432       did_shutdown = !!apdu_shutdown_reader (slot);
433
434       if ( cpr_get_answer_okay_cancel ("cardctrl.insert_card.okay",
435            _("Please insert the card and hit return or enter 'c' to cancel: "),
436                                        1) )
437         {
438           if (!did_shutdown)
439             apdu_close_reader (slot);
440           xfree (app);
441           goto retry;
442         }
443     }
444   if (rc)
445     {
446       write_status_text (STATUS_CARDCTRL, "4");
447       log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
448       apdu_close_reader (slot);
449       xfree (app);
450       return NULL;
451     }
452
453  ready:
454   app->initialized = 1;
455   current_app = app;
456   if (is_status_enabled () )
457     {
458       int i;
459       char *p, *buf;
460
461       buf = xmalloc (5 + app->serialnolen * 2 + 1);
462       p = stpcpy (buf, "3 ");
463       for (i=0; i < app->serialnolen; p +=2, i++)
464         sprintf (p, "%02X", app->serialno[i]);
465       write_status_text (STATUS_CARDCTRL, buf);
466       xfree (buf);
467     }
468
469   return app;
470 }
471
472
473 void
474 card_close (void)
475 {
476   if (current_app)
477     {
478       app_t app = current_app;
479       current_app = NULL;
480
481       if (app->assuan_ctx)
482         agent_close (app->assuan_ctx);
483       else
484         apdu_close_reader (app->slot);
485       xfree (app);
486     }
487 }
488
489
490 /* Format a cache ID from the serialnumber in SN and return it as an
491    allocated string.  In case of an error NULL is returned. */
492 static char *
493 format_cacheid (const char *sn)
494 {
495   const char *s;
496   size_t snlen;
497   char *cacheid = NULL;
498
499   /* The serialnumber we use for a card is "CARDSN:serialno".  Where
500      serialno is the BCD string (i.e. hex string) with the full
501      number.  The serial number expect here constsis of hexdigits
502      followed by other characters, we cut off these other
503      characters. */
504   if (sn)
505     {
506       for (s=sn,snlen=0; hexdigitp (s); s++, snlen++)
507         ;
508       if (snlen == 32)
509         {
510           /* Yes, this looks indeed like an OpenPGP card S/N. */
511           cacheid = xtrymalloc (7+snlen+1);
512           if (cacheid)
513             {
514               memcpy (cacheid, "CARDSN:", 7);
515               memcpy (cacheid+7, sn, snlen);
516               cacheid[7+snlen] = 0;
517             }
518         }
519     }
520   return cacheid;
521 }
522
523 /* Check that the serial number of the current card (as described by
524    APP) matches SERIALNO.  If there is no match and we are not in
525    batch mode, present a prompt to insert the desired card.  The
526    function return 0 is the present card is okay, -1 if the user
527    selected to insert a new card or an error value.  Note that the
528    card context will be closed in all cases except for 0 as return
529    value and if it was possible to merely shutdown the reader. */
530 static int
531 check_card_serialno (app_t app, const char *serialno)
532 {
533   const char *s;
534   int ask = 0;
535   int n;
536
537   for (s = serialno, n=0; *s != '/' && hexdigitp (s); s++, n++)
538     ;
539   if (n != 32)
540     {
541       log_error ("invalid serial number in keyring detected\n");
542       return gpg_error (GPG_ERR_INV_ID);
543     }
544   if (app->serialnolen != 16)
545     ask = 1;
546   for (s = serialno, n=0; !ask && n < 16; s += 2, n++)
547     if (app->serialno[n] != xtoi_2 (s))
548       ask = 1;
549   if (ask)
550     {
551       char buf[5+32+1];
552       int did_shutdown = 0;
553
554       if (current_app && !apdu_shutdown_reader (current_app->slot))
555         did_shutdown = 1;
556       else
557         card_close ();
558       tty_printf (_("Please remove the current card and "
559                     "insert the one with serial number:\n"
560                     "   %.*s\n"), 32, serialno);
561
562       sprintf (buf, "1 %.32s", serialno);
563       write_status_text (STATUS_CARDCTRL, buf);
564
565       if ( cpr_get_answer_okay_cancel ("cardctrl.change_card.okay",
566                           _("Hit return when ready "
567                             "or enter 'c' to cancel: "),
568                                        1) )
569         {
570           card_close ();
571           return -1;
572         }
573       if (did_shutdown)
574         apdu_reset (current_app->slot);
575       else
576         card_close ();
577       return gpg_error (GPG_ERR_INV_ID);
578     }
579   return 0;
580 }
581
582
583 /* Take a 20 byte hexencoded string and put it into the the provided
584    20 byte buffer FPR in binary format. */
585 static int
586 unhexify_fpr (const char *hexstr, unsigned char *fpr)
587 {
588   const char *s;
589   int n;
590
591   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
592     ;
593   if (*s || (n != 40))
594     return 0; /* no fingerprint (invalid or wrong length). */
595   n /= 2;
596   for (s=hexstr, n=0; *s; s += 2, n++)
597     fpr[n] = xtoi_2 (s);
598   return 1; /* okay */
599 }
600
601 /* Take the serial number from LINE and return it verbatim in a newly
602    allocated string.  We make sure that only hex characters are
603    returned. */
604 static char *
605 store_serialno (const char *line)
606 {
607   const char *s;
608   char *p;
609
610   for (s=line; hexdigitp (s); s++)
611     ;
612   p = xmalloc (s + 1 - line);
613   memcpy (p, line, s-line);
614   p[s-line] = 0;
615   return p;
616 }
617
618
619
620 static assuan_error_t
621 learn_status_cb (void *opaque, const char *line)
622 {
623   struct agent_card_info_s *parm = opaque;
624   const char *keyword = line;
625   int keywordlen;
626   int i;
627
628 /*   log_debug ("got status line `%s'\n", line); */
629   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
630     ;
631   while (spacep (line))
632     line++;
633
634   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
635     {
636       xfree (parm->serialno);
637       parm->serialno = store_serialno (line);
638     }
639   else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
640     {
641       xfree (parm->disp_name);
642       parm->disp_name = unescape_percent_string (line);
643     }
644   else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
645     {
646       xfree (parm->disp_lang);
647       parm->disp_lang = unescape_percent_string (line);
648     }
649   else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
650     {
651       parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
652     }
653   else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
654     {
655       xfree (parm->pubkey_url);
656       parm->pubkey_url = unescape_percent_string (line);
657     }
658   else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
659     {
660       xfree (parm->login_data);
661       parm->login_data = unescape_percent_string (line);
662     }
663   else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
664     {
665       parm->sig_counter = strtoul (line, NULL, 0);
666     }
667   else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
668     {
669       char *p, *buf;
670
671       buf = p = unescape_percent_string (line);
672       if (buf)
673         {
674           while (spacep (p))
675             p++;
676           parm->chv1_cached = atoi (p);
677           while (*p && !spacep (p))
678             p++;
679           while (spacep (p))
680             p++;
681           for (i=0; *p && i < 3; i++)
682             {
683               parm->chvmaxlen[i] = atoi (p);
684               while (*p && !spacep (p))
685                 p++;
686               while (spacep (p))
687                 p++;
688             }
689           for (i=0; *p && i < 3; i++)
690             {
691               parm->chvretry[i] = atoi (p);
692               while (*p && !spacep (p))
693                 p++;
694               while (spacep (p))
695                 p++;
696             }
697           xfree (buf);
698         }
699     }
700   else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
701     {
702       int no = atoi (line);
703       while (* line && !spacep (line))
704         line++;
705       while (spacep (line))
706         line++;
707       if (no == 1)
708         parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
709       else if (no == 2)
710         parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
711       else if (no == 3)
712         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
713     }
714   else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen))
715     {
716       int no = atoi (line);
717       while (* line && !spacep (line))
718         line++;
719       while (spacep (line))
720         line++;
721       if (no == 1)
722         parm->fpr1time = strtoul (line, NULL, 10);
723       else if (no == 2)
724         parm->fpr2time = strtoul (line, NULL, 10);
725       else if (no == 3)
726         parm->fpr3time = strtoul (line, NULL, 10);
727     }
728   else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen))
729     {
730       int no = atoi (line);
731       while (*line && !spacep (line))
732         line++;
733       while (spacep (line))
734         line++;
735       if (no == 1)
736         parm->cafpr1valid = unhexify_fpr (line, parm->cafpr1);
737       else if (no == 2)
738         parm->cafpr2valid = unhexify_fpr (line, parm->cafpr2);
739       else if (no == 3)
740         parm->cafpr3valid = unhexify_fpr (line, parm->cafpr3);
741     }
742   else if (keywordlen == 12 && !memcmp (keyword, "PRIVATE-DO-", 11)
743            && strchr ("1234", keyword[11]))
744     {
745       int no = keyword[11] - '1';
746       assert (no >= 0 && no <= 3);
747       xfree (parm->private_do[no]);
748       parm->private_do[no] = unescape_percent_string (line);
749     }
750  
751   return 0;
752 }
753
754
755 /* Return card info. */
756 int 
757 agent_learn (struct agent_card_info_s *info)
758 {
759   app_t app;
760   int rc;
761   struct ctrl_ctx_s ctrl;
762   time_t stamp;
763   char *serial;
764   
765   app = current_app? current_app : open_card ();
766   if (!app)
767     return gpg_error (GPG_ERR_CARD);
768
769   memset (info, 0, sizeof *info);
770
771   if (app->assuan_ctx)
772     {
773       rc = assuan_transact (app->assuan_ctx, "SCD LEARN --force",
774                             NULL, NULL, NULL, NULL,
775                             learn_status_cb, info);
776       rc = test_transact (rc, "SCD LEARN");
777     }
778   else
779     {
780       memset (&ctrl, 0, sizeof ctrl);
781       ctrl.status_cb = learn_status_cb;
782       ctrl.status_cb_arg = info;
783
784       rc = app_get_serial_and_stamp (app, &serial, &stamp);
785       if (!rc)
786         {
787           send_status_info (&ctrl, "SERIALNO",
788                             serial, strlen(serial), NULL, 0);
789           xfree (serial);
790           rc = app->fnc.learn_status (app, &ctrl);
791         }
792     }
793
794   return rc;
795 }
796
797
798 /* Get an attribute from the card. Make sure info is initialized. */
799 int 
800 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
801 {
802   int rc;
803   app_t app;
804   struct ctrl_ctx_s ctrl;
805
806   app = current_app? current_app : open_card ();
807   if (!app)
808     return gpg_error (GPG_ERR_CARD);
809
810   if (app->assuan_ctx)
811     {
812       char line[ASSUAN_LINELENGTH];
813
814       /* We assume that NAME does not need escaping. */
815       if (12 + strlen (name) > DIM(line)-1)
816         return gpg_error (GPG_ERR_CARD);
817       stpcpy (stpcpy (line, "SCD GETATTR "), name); 
818
819       rc = test_transact (assuan_transact (app->assuan_ctx, line,
820                                            NULL, NULL, NULL, NULL,
821                                            learn_status_cb, info),
822                           "SCD GETATTR");
823     }
824   else
825     {
826       ctrl.status_cb = learn_status_cb;
827       ctrl.status_cb_arg = info;
828       rc = app->fnc.getattr (app, &ctrl, name);
829     }
830
831   return rc;
832 }
833
834
835
836 static int 
837 pin_cb (void *opaque, const char *info, char **retstr)
838 {
839   struct pincb_parm_s *parm = opaque;
840   char *value;
841   int canceled;
842   int isadmin = 0;
843   int newpin = 0;
844   const char *again_text = NULL;
845   const char *ends, *s;
846   char *cacheid = NULL;
847
848   *retstr = NULL;
849   /*   log_debug ("asking for PIN '%s'\n", info); */
850
851   /* We use a special prefix to check whether the Admin PIN has been
852      requested. */
853   if (info && *info =='|' && (ends=strchr (info+1, '|')))
854     {
855       for (s=info+1; s < ends; s++)
856         {
857           if (*s == 'A')
858             isadmin = 1;
859           else if (*s == 'N')
860             newpin = 1;
861         }
862       info = ends+1;
863     }
864   else if (info && *info == '|')
865     log_debug ("pin_cb called without proper PIN info hack\n");
866
867   /* If we are not requesting a new PIN and we are not requesting an
868      AdminPIN, compute a string to be used as the cacheID for
869      gpg-agent. */
870   if (!newpin && !isadmin && parm)
871     {
872       cacheid = format_cacheid (parm->sn);
873     }
874   else if (newpin && parm)
875     {
876       /* Make really sure that it is not cached anymore. */
877       agent_clear_pin_cache (parm->sn);
878     }
879
880
881  again:
882   if (is_status_enabled())
883     write_status_text (STATUS_NEED_PASSPHRASE_PIN,
884                        isadmin? "OPENPGP 3" : "OPENPGP 1");
885
886   value = ask_passphrase (info, again_text,
887                           newpin && isadmin? "passphrase.adminpin.new.ask" :
888                           newpin?  "passphrase.pin.new.ask" :
889                           isadmin? "passphrase.adminpin.ask" :
890                                    "passphrase.pin.ask", 
891                           newpin && isadmin? _("Enter New Admin PIN: ") :
892                           newpin?  _("Enter New PIN: ") :
893                           isadmin? _("Enter Admin PIN: ")
894                                  : _("Enter PIN: "),
895                           cacheid,
896                           &canceled);
897   xfree (cacheid);
898   cacheid = NULL;
899   again_text = NULL;
900   if (!value && canceled)
901     return -1;
902   else if (!value)
903     return G10ERR_GENERAL;
904
905   if (newpin)
906     {
907       char *value2;
908
909       value2 = ask_passphrase (info, NULL, NULL,
910                                "passphrase.pin.repeat", 
911                                _("Repeat this PIN: "),
912                               &canceled);
913       if (!value && canceled)
914         {
915           xfree (value);
916           return -1;
917         }
918       else if (!value)
919         {
920           xfree (value);
921           return G10ERR_GENERAL;
922         }
923       if (strcmp (value, value2))
924         {
925           again_text = N_("PIN not correctly repeated; try again");
926           xfree (value2);
927           xfree (value);
928           value = NULL;
929           goto again;
930         }
931       xfree (value2);
932     }
933
934   *retstr = value;
935   return 0;
936 }
937
938
939
940 /* Send a SETATTR command to the SCdaemon. */
941 int 
942 agent_scd_setattr (const char *name,
943                    const unsigned char *value, size_t valuelen)
944 {
945   app_t app;
946   int rc;
947
948   app = current_app? current_app : open_card ();
949   if (!app)
950     return gpg_error (GPG_ERR_CARD);
951
952   if (app->assuan_ctx)
953     {
954       char line[ASSUAN_LINELENGTH];
955       char *p;
956
957       /* We assume that NAME does not need escaping. */
958       if (12 + strlen (name) > DIM(line)-1)
959         return gpg_error (GPG_ERR_CARD);
960       p = stpcpy (stpcpy (line, "SCD SETATTR "), name); 
961       *p++ = ' ';
962       for (; valuelen; value++, valuelen--)
963         {
964           if (p >= line + DIM(line)-5 )
965             return gpg_error (GPG_ERR_CARD);
966           if (*value < ' ' || *value == '+' || *value == '%')
967             {
968               sprintf (p, "%%%02X", *value);
969               p += 3;
970             }
971           else if (*value == ' ')
972             *p++ = '+';
973           else
974             *p++ = *value;
975         }
976       *p = 0;
977
978       rc = test_transact (assuan_transact (app->assuan_ctx, line,
979                                            NULL, NULL, NULL, NULL, NULL, NULL),
980                           "SCD SETATTR");
981     }
982   else
983     {
984       rc = app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen);
985     }
986
987   if (rc)
988     write_status (STATUS_SC_OP_FAILURE);
989   return rc;
990 }
991
992
993 /* Handle a KEYDATA inquiry.  Note, we only send the data,
994    assuan_transact takes care of flushing and writing the end */
995 static assuan_error_t
996 inq_writekey_parms (void *opaque, const char *keyword)
997 {
998   struct writekey_parm_s *parm = opaque; 
999
1000   return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
1001 }
1002
1003
1004 /* Send a WRITEKEY command to the SCdaemon. */
1005 int 
1006 agent_scd_writekey (int keyno, const unsigned char *keydata, size_t keydatalen)
1007 {
1008   app_t app;
1009   int rc;
1010   char line[ASSUAN_LINELENGTH];
1011   app = current_app? current_app : open_card ();
1012   if (!app)
1013     return gpg_error (GPG_ERR_CARD);
1014
1015   if (app->assuan_ctx)
1016     {
1017       struct writekey_parm_s parms;
1018
1019       snprintf (line, DIM(line)-1, "SCD WRITEKEY --force OPENPGP.%d", keyno);
1020       line[DIM(line)-1] = 0;
1021       parms.ctx = app->assuan_ctx;
1022       parms.keydata = keydata;
1023       parms.keydatalen = keydatalen;
1024       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1025                                            NULL, NULL,
1026                                            inq_writekey_parms, &parms,
1027                                            NULL, NULL),
1028                           "SCD WRITEKEY");
1029     }
1030   else
1031     {
1032       snprintf (line, DIM(line)-1, "OPENPGP.%d", keyno);
1033       line[DIM(line)-1] = 0;
1034       rc = app->fnc.writekey (app, NULL, line, 0x0001,
1035                               pin_cb, NULL,
1036                               keydata, keydatalen);
1037     }
1038
1039   if (rc)
1040     write_status (STATUS_SC_OP_FAILURE);
1041   return rc;
1042 }
1043
1044
1045
1046 static assuan_error_t
1047 genkey_status_cb (void *opaque, const char *line)
1048 {
1049   struct agent_card_genkey_s *parm = opaque;
1050   const char *keyword = line;
1051   int keywordlen;
1052
1053 /*   log_debug ("got status line `%s'\n", line); */
1054   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
1055     ;
1056   while (spacep (line))
1057     line++;
1058
1059   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
1060     {
1061       parm->fprvalid = unhexify_fpr (line, parm->fpr);
1062     }
1063   if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
1064     {
1065       MPI a;
1066       const char *name = line;
1067       char *buf;
1068
1069       while (*line && !spacep (line))
1070         line++;
1071       while (spacep (line))
1072         line++;
1073
1074       buf = xmalloc ( 2 + strlen (line) + 1);
1075       strcpy (stpcpy (buf, "0x"), line);
1076       a = mpi_alloc (300);
1077       if( mpi_fromstr (a, buf) )
1078         log_error ("error parsing received key data\n");
1079       else if (*name == 'n' && spacep (name+1))
1080         parm->n = a;
1081       else if (*name == 'e' && spacep (name+1))
1082         parm->e = a;
1083       else
1084         {
1085           log_info ("unknown parameter name in received key data\n");
1086           mpi_free (a);
1087         }
1088       xfree (buf);
1089     }
1090   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
1091     {
1092       parm->created_at = (u32)strtoul (line, NULL, 10);
1093     }
1094
1095   return 0;
1096 }
1097
1098 /* Send a GENKEY command to the SCdaemon. */
1099 int 
1100 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force)
1101 {
1102   app_t app;
1103   char line[ASSUAN_LINELENGTH];
1104   struct ctrl_ctx_s ctrl;
1105   int rc;
1106
1107   app = current_app? current_app : open_card ();
1108   if (!app)
1109     return gpg_error (GPG_ERR_CARD);
1110
1111   memset (info, 0, sizeof *info);
1112
1113   if (app->assuan_ctx)
1114     {
1115       snprintf (line, DIM(line)-1, "SCD GENKEY %s%d",
1116                 force? "--force ":"", keyno);
1117       line[DIM(line)-1] = 0;
1118       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1119                                            NULL, NULL, NULL, NULL,
1120                                            genkey_status_cb, info),
1121                           "SCD GENKEY");
1122     }
1123   else
1124     {
1125       snprintf (line, DIM(line)-1, "%d", keyno);
1126       ctrl.status_cb = genkey_status_cb;
1127       ctrl.status_cb_arg = info;
1128       rc = app->fnc.genkey (app, &ctrl, line,
1129                             force? 1:0,
1130                             pin_cb, NULL);
1131     }
1132
1133   if (rc)
1134     write_status (STATUS_SC_OP_FAILURE);
1135   return rc;
1136 }
1137
1138
1139 static assuan_error_t
1140 membuf_data_cb (void *opaque, const void *buffer, size_t length)
1141 {
1142   membuf_t *data = opaque;
1143
1144   if (buffer)
1145     put_membuf (data, buffer, length);
1146   return 0;
1147 }
1148   
1149
1150 /* Send a PKSIGN command to the SCdaemon. */
1151 int 
1152 agent_scd_pksign (const char *serialno, int hashalgo,
1153                   const unsigned char *indata, size_t indatalen,
1154                   unsigned char **r_buf, size_t *r_buflen)
1155 {
1156   struct pincb_parm_s parm;
1157   app_t app;
1158   int rc;
1159
1160   *r_buf = NULL;
1161   *r_buflen = 0;
1162   memset (&parm, 0, sizeof parm);
1163   parm.sn = serialno;
1164  retry:
1165   app = current_app? current_app : open_card ();
1166   if (!app)
1167     return gpg_error (GPG_ERR_CARD);
1168
1169   if (app->assuan_ctx)
1170     {
1171       char *p, line[ASSUAN_LINELENGTH];
1172       membuf_t data;
1173       size_t len;
1174       int i;
1175
1176       if (indatalen*2 + 50 > DIM(line))
1177         return gpg_error (GPG_ERR_GENERAL);
1178
1179       p = stpcpy (line, "SCD SETDATA ");
1180       for (i=0; i < indatalen ; i++, p += 2 )
1181         sprintf (p, "%02X", indata[i]);
1182       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1183                                            NULL, NULL, NULL, NULL, NULL, NULL),
1184                           "SCD SETDATA");
1185       if (!rc)
1186         {
1187           init_membuf (&data, 1024);
1188           snprintf (line, DIM(line)-1, "SCD PKSIGN %s", serialno);
1189           line[DIM(line)-1] = 0;
1190           rc = test_transact (assuan_transact (app->assuan_ctx, line,
1191                                                membuf_data_cb, &data,
1192                                                NULL, NULL, NULL, NULL),
1193                               "SCD PKSIGN");
1194           if (rc)
1195             xfree (get_membuf (&data, &len));
1196           else
1197             *r_buf = get_membuf (&data, r_buflen);
1198         }
1199     }
1200   else
1201     {
1202       /* Check that the card's serialnumber is as required.*/
1203       rc = check_card_serialno (app, serialno);
1204       if (rc == -1)
1205         goto retry;
1206
1207       if (!rc)
1208         rc = app->fnc.sign (app, serialno, hashalgo,
1209                             pin_cb, &parm,
1210                             indata, indatalen,
1211                             r_buf, r_buflen);
1212     }
1213
1214   if (rc)
1215     {
1216       write_status (STATUS_SC_OP_FAILURE);
1217       if (!app->assuan_ctx)
1218         agent_clear_pin_cache (serialno);
1219     }
1220   return rc;
1221 }
1222
1223
1224 /* Send a PKDECRYPT command to the SCdaemon. */
1225 int 
1226 agent_scd_pkdecrypt (const char *serialno,
1227                      const unsigned char *indata, size_t indatalen,
1228                      unsigned char **r_buf, size_t *r_buflen)
1229 {
1230   struct pincb_parm_s parm;
1231   app_t app;
1232   int rc;
1233
1234   *r_buf = NULL;
1235   *r_buflen = 0;
1236   memset (&parm, 0, sizeof parm);
1237   parm.sn = serialno;
1238  retry:
1239   app = current_app? current_app : open_card ();
1240   if (!app)
1241     return gpg_error (GPG_ERR_CARD);
1242
1243   if (app->assuan_ctx)
1244     {
1245       char *p, line[ASSUAN_LINELENGTH];
1246       membuf_t data;
1247       size_t len;
1248       int i;
1249
1250       if (indatalen*2 + 50 > DIM(line))
1251         return gpg_error (GPG_ERR_GENERAL);
1252
1253       p = stpcpy (line, "SCD SETDATA ");
1254       for (i=0; i < indatalen ; i++, p += 2 )
1255         sprintf (p, "%02X", indata[i]);
1256       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1257                                            NULL, NULL, NULL, NULL, NULL, NULL),
1258                           "SCD SETDATA");
1259       if (!rc)
1260         {
1261           init_membuf (&data, 1024);
1262           snprintf (line, DIM(line)-1, "SCD PKDECRYPT %s", serialno);
1263           line[DIM(line)-1] = 0;
1264           rc = test_transact (assuan_transact (app->assuan_ctx, line,
1265                                                membuf_data_cb, &data,
1266                                                NULL, NULL, NULL, NULL),
1267                               "SCD PKDECRYPT");
1268           if (rc)
1269             xfree (get_membuf (&data, &len));
1270           else
1271             *r_buf = get_membuf (&data, r_buflen);
1272         }
1273     }
1274   else
1275     {
1276       /* Check that the card's serialnumber is as required.*/
1277       rc = check_card_serialno (app, serialno);
1278       if (rc == -1)
1279         goto retry;
1280       
1281       if (!rc)
1282         rc = app->fnc.decipher (app, serialno, 
1283                                 pin_cb, &parm,
1284                                 indata, indatalen,
1285                                 r_buf, r_buflen);
1286     }
1287
1288   if (rc)
1289     {
1290       write_status (STATUS_SC_OP_FAILURE);
1291       if (!app->assuan_ctx)
1292         agent_clear_pin_cache (serialno);
1293     }
1294   return rc;
1295 }
1296
1297 /* Change the PIN of an OpenPGP card or reset the retry counter. */
1298 int 
1299 agent_scd_change_pin (int chvno)
1300 {
1301   app_t app;
1302   int reset = 0;
1303   int rc;
1304
1305   reset = (chvno >= 100);
1306   chvno %= 100;
1307
1308   app = current_app? current_app : open_card ();
1309   if (!app)
1310     return gpg_error (GPG_ERR_CARD);
1311
1312   if (app->assuan_ctx)
1313     {
1314       char line[ASSUAN_LINELENGTH];
1315
1316       snprintf (line, DIM(line)-1, "SCD PASSWD%s %d",
1317                 reset? " --reset":"", chvno);
1318       line[DIM(line)-1] = 0;
1319       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1320                                            NULL, NULL, NULL, NULL, NULL, NULL),
1321                           "SCD PASSWD");
1322     }
1323   else
1324     {
1325       char chvnostr[50];
1326
1327       sprintf (chvnostr, "%d", chvno);
1328       rc = app->fnc.change_pin (app, NULL, chvnostr, reset,
1329                                 pin_cb, NULL);
1330     }
1331
1332   if (rc)
1333     write_status (STATUS_SC_OP_FAILURE);
1334   return rc;
1335 }
1336
1337 /* Perform a CHECKPIN operation.  SERIALNO should be the serial
1338    number of the card - optionally followed by the fingerprint;
1339    however the fingerprint is ignored here. */
1340 int
1341 agent_scd_checkpin (const char *serialnobuf)
1342 {
1343   app_t app;
1344   int rc;
1345
1346   app = current_app? current_app : open_card ();
1347   if (!app)
1348     return gpg_error (GPG_ERR_CARD);
1349
1350   if (app->assuan_ctx)
1351     {
1352       char line[ASSUAN_LINELENGTH];
1353
1354       if (15 + strlen (serialnobuf) > DIM(line)-1)
1355         return gpg_error (GPG_ERR_CARD);
1356       stpcpy (stpcpy (line, "SCD CHECKPIN "), serialnobuf); 
1357       rc = test_transact (assuan_transact (app->assuan_ctx, line,
1358                                            NULL, NULL, NULL, NULL, NULL, NULL),
1359                           "SCD CHECKPIN");
1360     }
1361   else
1362     {
1363       rc = app->fnc.check_pin (app, serialnobuf, pin_cb, NULL);
1364     }
1365
1366   if (rc)
1367     write_status (STATUS_SC_OP_FAILURE);
1368   return rc;
1369 }
1370
1371
1372
1373 void
1374 agent_clear_pin_cache (const char *sn)
1375 {
1376   char *cacheid = format_cacheid (sn);
1377   if (cacheid)
1378     {
1379       passphrase_clear_cache (NULL, cacheid, 0);
1380       xfree (cacheid);
1381     }
1382 }