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