* plaintext.c (handle_plaintext): Accept 'u' as a plaintext mode that
[gnupg.git] / g10 / cardglue.c
1 /* cardglue.c - mainly dispatcher for card related functions.
2  * Copyright (C) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #ifndef ENABLE_CARD_SUPPORT
23 #error  not configured for card support.
24 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <stdarg.h>
30 #include <assert.h>
31
32 #include "options.h"
33 #include "packet.h"
34 #include "errors.h"
35 #include "memory.h"
36 #include "util.h"
37 #include "main.h"
38 #include "status.h"
39 #include "ttyio.h"
40 #include "i18n.h"
41
42 #include "cardglue.h"
43 #include "apdu.h"
44 #include "app-common.h"
45
46 struct ctrl_ctx_s {
47   int (*status_cb)(void *opaque, const char *line);
48   void *status_cb_arg;
49 };
50
51
52 static char *default_reader_port;
53 static APP current_app;
54
55
56
57
58 /* Create a serialno/fpr string from the serial number and the secret
59    key.  caller must free the returned string.  There is no error
60    return. [Taken from 1.9's keyid.c]*/
61 char *
62 serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
63                           PKT_secret_key *sk)
64 {
65   unsigned char fpr[MAX_FINGERPRINT_LEN];
66   size_t fprlen;
67   char *buffer, *p;
68   int i;
69   
70   fingerprint_from_sk (sk, fpr, &fprlen);
71   buffer = p = xmalloc (snlen*2 + 1 + fprlen*2 + 1);
72   for (i=0; i < snlen; i++, p+=2)
73     sprintf (p, "%02X", sn[i]);
74   *p++ = '/';
75   for (i=0; i < fprlen; i++, p+=2)
76     sprintf (p, "%02X", fpr[i]);
77   *p = 0;
78   return buffer;
79 }
80
81
82 /* Send a line with status information via assuan and escape all given
83    buffers. The variable elements are pairs of (char *, size_t),
84    terminated with a (NULL, 0). */
85 void
86 send_status_info (CTRL ctrl, const char *keyword, ...)
87 {
88   va_list arg_ptr;
89   const unsigned char *value;
90   size_t valuelen;
91   char buf[950], *p;
92   size_t n;
93   
94   va_start (arg_ptr, keyword);
95
96   p = buf; 
97   n = 0;
98   valuelen = strlen (keyword);
99   for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, keyword++)
100     *p++ = *keyword;
101
102   while ( (value = va_arg (arg_ptr, const unsigned char *)) )
103     {
104       valuelen = va_arg (arg_ptr, size_t);
105       if (!valuelen)
106         continue; /* empty buffer */
107       if (n)
108         {
109           *p++ = ' ';
110           n++;
111         }
112       for ( ; valuelen && n < DIM (buf)-2; n++, valuelen--, value++)
113         {
114           if (*value < ' ' || *value == '+')
115             {
116               sprintf (p, "%%%02X", *value);
117               p += 3;
118             }
119           else if (*value == ' ')
120             *p++ = '+';
121           else
122             *p++ = *value;
123         }
124     }
125   *p = 0;
126   ctrl->status_cb (ctrl->status_cb_arg, buf);
127
128   va_end (arg_ptr);
129 }
130
131
132 void gcry_md_hash_buffer (int algo, void *digest,
133                           const void *buffer, size_t length)
134 {
135   MD_HANDLE h = md_open (algo, 0);
136   if (!h)
137     BUG();
138   md_write (h, (byte *) buffer, length);
139   md_final (h);
140   memcpy (digest, md_read (h, algo), md_digest_length (algo));
141   md_close (h);
142 }
143
144
145 /* This is a limited version of the one in 1.9 but it should be
146    sufficient here. */
147 void
148 log_printf (const char *fmt, ...)
149 {
150   va_list arg_ptr;
151
152   va_start (arg_ptr, fmt);
153   vfprintf (log_stream (), fmt, arg_ptr);
154   va_end (arg_ptr);
155 }
156
157
158
159 /* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
160    dump, with TEXT just an empty string, print a trailing linefeed,
161    otherwise print an entire debug line. */
162 void
163 log_printhex (const char *text, const void *buffer, size_t length)
164 {
165   if (text && *text)
166     log_debug ("%s ", text);
167   if (length)
168     {
169       const unsigned char *p = buffer;
170       log_printf ("%02X", *p);
171       for (length--, p++; length--; p++)
172         log_printf (" %02X", *p);
173     }
174   if (text)
175     log_printf ("\n");
176 }
177
178
179
180 void
181 app_set_default_reader_port (const char *portstr)
182 {
183   xfree (default_reader_port);
184   default_reader_port = portstr? xstrdup (portstr): NULL;
185 }
186
187
188 void
189 card_set_reader_port (const char *portstr)
190 {
191   app_set_default_reader_port (portstr);
192 }
193
194
195 /* Retrieve the serial number and the time of the last update of the
196    card.  The serial number is returned as a malloced string (hex
197    encoded) in SERIAL and the time of update is returned in STAMP.  If
198    no update time is available the returned value is 0.  Caller must
199    free SERIAL unless the function returns an error. */
200 int 
201 app_get_serial_and_stamp (APP app, char **serial, time_t *stamp)
202 {
203   unsigned char *buf, *p;
204   int i;
205
206   if (!app || !serial || !stamp)
207     return gpg_error (GPG_ERR_INV_VALUE);
208
209   *serial = NULL;
210   *stamp = 0; /* not available */
211
212   buf = xtrymalloc (app->serialnolen * 2 + 1);
213   if (!buf)
214     return gpg_error_from_errno (errno);
215   for (p=buf, i=0; i < app->serialnolen; p +=2, i++)
216     sprintf (p, "%02X", app->serialno[i]);
217   *p = 0;
218   *serial = buf;
219   return 0;
220 }
221
222
223
224
225
226
227 /* Release the card info structure. */
228 void 
229 agent_release_card_info (struct agent_card_info_s *info)
230 {
231   if (!info)
232     return;
233
234   xfree (info->serialno); info->serialno = NULL;
235   xfree (info->disp_name); info->disp_name = NULL;
236   xfree (info->disp_lang); info->disp_lang = NULL;
237   xfree (info->pubkey_url); info->pubkey_url = NULL;
238   xfree (info->login_data); info->login_data = NULL;
239   info->fpr1valid = info->fpr2valid = info->fpr3valid = 0;
240 }
241
242
243 /* Open the current card and select the openpgp application.  Return
244    an APP context handle to be used for further procesing or NULL on
245    error or if no OpenPGP application exists.*/
246 static APP
247 open_card (void)
248 {
249   int slot;
250   int rc;
251   APP app;
252
253   card_close ();
254
255  retry:
256   slot = apdu_open_reader (default_reader_port);
257   if (slot == -1)
258     {
259       log_error ("card reader not available\n");
260       return NULL;
261     }
262
263   app = xcalloc (1, sizeof *app);
264   app->slot = slot;
265   rc = app_select_openpgp (app, &app->serialno, &app->serialnolen);
266   if (rc && !opt.batch)
267     {
268       write_status_text (STATUS_CARDCTRL, "1");
269       
270       if ( cpr_get_answer_okay_cancel ("cardctrl.insert_card.okay",
271            _("Please insert the card and hit return or enter 'c' to cancel: "),
272                                        1) )
273         {
274           apdu_close_reader (slot);
275           xfree (app);
276           goto retry;
277         }
278     }
279   if (rc)
280     {
281       log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
282       apdu_close_reader (slot);
283       xfree (app);
284       return NULL;
285     }
286
287   app->initialized = 1;
288   current_app = app;
289   if (is_status_enabled () )
290     {
291       int i;
292       char *p, *buf;
293
294       buf = xmalloc (5 + app->serialnolen * 2 + 1);
295       p = stpcpy (buf, "3 ");
296       for (i=0; i < app->serialnolen; p +=2, i++)
297         sprintf (p, "%02X", app->serialno[i]);
298       write_status_text (STATUS_CARDCTRL, buf);
299       xfree (buf);
300     }
301
302   return app;
303 }
304
305 void
306 card_close (void)
307 {
308   if (current_app)
309     {
310       APP app = current_app;
311       current_app = NULL;
312
313       apdu_close_reader (app->slot);
314       xfree (app);
315     }
316 }
317
318
319 /* Check that the serial number of the current card (as described by
320    APP) matches SERIALNO.  If there is no match and we are not in
321    batch mode, present a prompt to insert the desired card.  The
322    function return 0 is the present card is okay, -1 if the user
323    selected to insert a new card or an error value.  Note that the
324    card context will be closed in all cases except for 0 as return
325    value. */
326 static int
327 check_card_serialno (APP app, const char *serialno)
328 {
329   const char *s;
330   int ask = 0;
331   int n;
332   
333   for (s = serialno, n=0; *s != '/' && hexdigitp (s); s++, n++)
334     ;
335   if (n != 32)
336     {
337       log_error ("invalid serial number in keyring detected\n");
338       return gpg_error (GPG_ERR_INV_ID);
339     }
340   if (app->serialnolen != 16)
341     ask = 1;
342   for (s = serialno, n=0; !ask && n < 16; s += 2, n++)
343     if (app->serialno[n] != xtoi_2 (s))
344       ask = 1;
345   if (ask)
346     {
347       char buf[5+32+1];
348
349       card_close ();
350       tty_printf (_("Please remove the current card and "
351                     "insert the one with the serial number:\n"
352                     "   %.*s\n"), 32, serialno);
353
354       sprintf (buf, "1 %.32s", serialno);
355       write_status_text (STATUS_CARDCTRL, buf);
356
357       if ( cpr_get_answer_okay_cancel ("cardctrl.change_card.okay",
358                           _("Hit return when ready "
359                             "or enter 'c' to cancel: "),
360                                        1) )
361         return -1;
362       return gpg_error (GPG_ERR_INV_ID);
363     }
364   return 0;
365 }
366
367
368
369 /* Return a new malloced string by unescaping the string S.  Escaping
370    is percent escaping and '+'/space mapping.  A binary nul will
371    silently be replaced by a 0xFF.  Function returns NULL to indicate
372    an out of memory status. */
373 static char *
374 unescape_status_string (const unsigned char *s)
375 {
376   char *buffer, *d;
377
378   buffer = d = xmalloc (strlen (s)+1);
379   while (*s)
380     {
381       if (*s == '%' && s[1] && s[2])
382         { 
383           s++;
384           *d = xtoi_2 (s);
385           if (!*d)
386             *d = '\xff';
387           d++;
388           s += 2;
389         }
390       else if (*s == '+')
391         {
392           *d++ = ' ';
393           s++;
394         }
395       else
396         *d++ = *s++;
397     }
398   *d = 0; 
399   return buffer;
400 }
401
402 /* Take a 20 byte hexencoded string and put it into the the provided
403    20 byte buffer FPR in binary format. */
404 static int
405 unhexify_fpr (const char *hexstr, unsigned char *fpr)
406 {
407   const char *s;
408   int n;
409
410   for (s=hexstr, n=0; hexdigitp (s); s++, n++)
411     ;
412   if (*s || (n != 40))
413     return 0; /* no fingerprint (invalid or wrong length). */
414   n /= 2;
415   for (s=hexstr, n=0; *s; s += 2, n++)
416     fpr[n] = xtoi_2 (s);
417   return 1; /* okay */
418 }
419
420 /* Take the serial number from LINE and return it verbatim in a newly
421    allocated string.  We make sure that only hex characters are
422    returned. */
423 static char *
424 store_serialno (const char *line)
425 {
426   const char *s;
427   char *p;
428
429   for (s=line; hexdigitp (s); s++)
430     ;
431   p = xmalloc (s + 1 - line);
432   memcpy (p, line, s-line);
433   p[s-line] = 0;
434   return p;
435 }
436
437
438
439 static int
440 learn_status_cb (void *opaque, const char *line)
441 {
442   struct agent_card_info_s *parm = opaque;
443   const char *keyword = line;
444   int keywordlen;
445   int i;
446
447   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
448     ;
449   while (spacep (line))
450     line++;
451
452   if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen))
453     {
454       xfree (parm->serialno);
455       parm->serialno = store_serialno (line);
456     }
457   else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen))
458     {
459       xfree (parm->disp_name);
460       parm->disp_name = unescape_status_string (line);
461     }
462   else if (keywordlen == 9 && !memcmp (keyword, "DISP-LANG", keywordlen))
463     {
464       xfree (parm->disp_lang);
465       parm->disp_lang = unescape_status_string (line);
466     }
467   else if (keywordlen == 8 && !memcmp (keyword, "DISP-SEX", keywordlen))
468     {
469       parm->disp_sex = *line == '1'? 1 : *line == '2' ? 2: 0;
470     }
471   else if (keywordlen == 10 && !memcmp (keyword, "PUBKEY-URL", keywordlen))
472     {
473       xfree (parm->pubkey_url);
474       parm->pubkey_url = unescape_status_string (line);
475     }
476   else if (keywordlen == 10 && !memcmp (keyword, "LOGIN-DATA", keywordlen))
477     {
478       xfree (parm->login_data);
479       parm->login_data = unescape_status_string (line);
480     }
481   else if (keywordlen == 11 && !memcmp (keyword, "SIG-COUNTER", keywordlen))
482     {
483       parm->sig_counter = strtoul (line, NULL, 0);
484     }
485   else if (keywordlen == 10 && !memcmp (keyword, "CHV-STATUS", keywordlen))
486     {
487       char *p, *buf;
488
489       buf = p = unescape_status_string (line);
490       if (buf)
491         {
492           while (spacep (p))
493             p++;
494           parm->chv1_cached = atoi (p);
495           while (*p && !spacep (p))
496             p++;
497           while (spacep (p))
498             p++;
499           for (i=0; *p && i < 3; i++)
500             {
501               parm->chvmaxlen[i] = atoi (p);
502               while (*p && !spacep (p))
503                 p++;
504               while (spacep (p))
505                 p++;
506             }
507           for (i=0; *p && i < 3; i++)
508             {
509               parm->chvretry[i] = atoi (p);
510               while (*p && !spacep (p))
511                 p++;
512               while (spacep (p))
513                 p++;
514             }
515           xfree (buf);
516         }
517     }
518   else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
519     {
520       int no = atoi (line);
521       while (* line && !spacep (line))
522         line++;
523       while (spacep (line))
524         line++;
525       if (no == 1)
526         parm->fpr1valid = unhexify_fpr (line, parm->fpr1);
527       else if (no == 2)
528         parm->fpr2valid = unhexify_fpr (line, parm->fpr2);
529       else if (no == 3)
530         parm->fpr3valid = unhexify_fpr (line, parm->fpr3);
531     }
532   
533   return 0;
534 }
535
536
537 /* Return card info. */
538 int 
539 agent_learn (struct agent_card_info_s *info)
540 {
541   APP app;
542   int rc;
543   struct ctrl_ctx_s ctrl;
544   time_t stamp;
545   char *serial;
546   
547   app = current_app? current_app : open_card ();
548   if (!app)
549     return gpg_error (GPG_ERR_CARD);
550
551   memset (info, 0, sizeof *info);
552   memset (&ctrl, 0, sizeof ctrl);
553   ctrl.status_cb = learn_status_cb;
554   ctrl.status_cb_arg = info;
555
556   rc = app_get_serial_and_stamp (app, &serial, &stamp);
557   if (!rc)
558     {
559       send_status_info (&ctrl, "SERIALNO", serial, strlen(serial), NULL, 0);
560       xfree (serial);
561       rc = app->fnc.learn_status (app, &ctrl);
562     }
563
564   return rc;
565 }
566
567 /* Get an attribite from the card. Make sure info is initialized. */
568 int 
569 agent_scd_getattr (const char *name, struct agent_card_info_s *info)
570 {
571   APP app;
572   struct ctrl_ctx_s ctrl;
573
574   app = current_app? current_app : open_card ();
575   if (!app)
576     return gpg_error (GPG_ERR_CARD);
577
578   ctrl.status_cb = learn_status_cb;
579   ctrl.status_cb_arg = info;
580   return app->fnc.getattr (app, &ctrl, name);
581 }
582
583
584
585 static int 
586 pin_cb (void *opaque, const char *info, char **retstr)
587 {
588   char *value;
589   int canceled;
590   int isadmin = (info && strstr (info, "dmin"));
591
592
593   *retstr = NULL;
594   log_debug ("asking for PIN '%s'\n", info);
595
596   value = ask_passphrase (info, 
597                           isadmin? "passphrase.adminpin.ask"
598                                  : "passphrase.pin.ask", 
599                           isadmin?  _("Enter Admin PIN: ") : _("Enter PIN: "),
600                           &canceled);
601   if (!value && canceled)
602     return -1;
603   else if (!value)
604     return G10ERR_GENERAL;
605
606   *retstr = value;
607   return 0;
608 }
609
610
611
612 /* Send a SETATTR command to the SCdaemon. */
613 int 
614 agent_scd_setattr (const char *name,
615                    const unsigned char *value, size_t valuelen)
616 {
617   APP app;
618
619   app = current_app? current_app : open_card ();
620   if (!app)
621     return gpg_error (GPG_ERR_CARD);
622
623   return app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen);
624 }
625
626
627 static int
628 genkey_status_cb (void *opaque, const char *line)
629 {
630   struct agent_card_genkey_s *parm = opaque;
631   const char *keyword = line;
632   int keywordlen;
633
634   log_debug ("got status line `%s'\n", line);
635   for (keywordlen=0; *line && !spacep (line); line++, keywordlen++)
636     ;
637   while (spacep (line))
638     line++;
639
640   if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen))
641     {
642       parm->fprvalid = unhexify_fpr (line, parm->fpr);
643     }
644   if (keywordlen == 8 && !memcmp (keyword, "KEY-DATA", keywordlen))
645     {
646       MPI a;
647       const char *name = line;
648       char *buf;
649
650       while (*line && !spacep (line))
651         line++;
652       while (spacep (line))
653         line++;
654
655       buf = xmalloc ( 2 + strlen (line) + 1);
656       strcpy (stpcpy (buf, "0x"), line);
657       a = mpi_alloc (300);
658       if( mpi_fromstr (a, buf) )
659         log_error ("error parsing received key data\n");
660       else if (*name == 'n' && spacep (name+1))
661         parm->n = a;
662       else if (*name == 'e' && spacep (name+1))
663         parm->e = a;
664       else
665         {
666           log_info ("unknown parameter name in received key data\n");
667           mpi_free (a);
668         }
669       xfree (buf);
670     }
671   else if (keywordlen == 14 && !memcmp (keyword,"KEY-CREATED-AT", keywordlen))
672     {
673       parm->created_at = (u32)strtoul (line, NULL, 10);
674     }
675
676   return 0;
677 }
678
679 /* Send a GENKEY command to the SCdaemon. */
680 int 
681 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force)
682 {
683   APP app;
684   char keynostr[20];
685   struct ctrl_ctx_s ctrl;
686
687   app = current_app? current_app : open_card ();
688   if (!app)
689     return gpg_error (GPG_ERR_CARD);
690
691   memset (info, 0, sizeof *info);
692   sprintf (keynostr, "%d", keyno);
693   ctrl.status_cb = genkey_status_cb;
694   ctrl.status_cb_arg = info;
695
696   return app->fnc.genkey (app, &ctrl, keynostr,
697                            force? 1:0,
698                            pin_cb, NULL);
699 }
700
701 /* Send a PKSIGN command to the SCdaemon. */
702 int 
703 agent_scd_pksign (const char *serialno, int hashalgo,
704                   const unsigned char *indata, size_t indatalen,
705                   unsigned char **r_buf, size_t *r_buflen)
706 {
707   APP app;
708   int rc;
709
710   *r_buf = NULL;
711   *r_buflen = 0;
712  retry:
713   app = current_app? current_app : open_card ();
714   if (!app)
715     return gpg_error (GPG_ERR_CARD);
716
717   /* Check that the card's serialnumber is as required.*/
718   rc = check_card_serialno (app, serialno);
719   if (rc == -1)
720     goto retry;
721   if (rc)
722     return rc;
723
724   return app->fnc.sign (app, serialno, hashalgo,
725                         pin_cb, NULL,
726                         indata, indatalen,
727                         r_buf, r_buflen);
728 }
729
730
731 /* Send a PKDECRYPT command to the SCdaemon. */
732 int 
733 agent_scd_pkdecrypt (const char *serialno,
734                      const unsigned char *indata, size_t indatalen,
735                      unsigned char **r_buf, size_t *r_buflen)
736 {
737   APP app;
738   int rc;
739
740   *r_buf = NULL;
741   *r_buflen = 0;
742  retry:
743   app = current_app? current_app : open_card ();
744   if (!app)
745     return gpg_error (GPG_ERR_CARD);
746
747   /* Check that the card's serialnumber is as required.*/
748   rc = check_card_serialno (app, serialno);
749   if (rc == -1)
750     goto retry;
751   if (rc)
752     return rc;
753
754   return app->fnc.decipher (app, serialno, 
755                             pin_cb, NULL,
756                             indata, indatalen,
757                             r_buf, r_buflen);
758 }
759
760 /* Change the PIN of an OpenPGP card or reset the retry counter. */
761 int 
762 agent_scd_change_pin (int chvno)
763 {
764   APP app;
765   char chvnostr[20];
766   int reset = 0;
767
768   reset = (chvno >= 100);
769   chvno %= 100;
770
771   app = current_app? current_app : open_card ();
772   if (!app)
773     return gpg_error (GPG_ERR_CARD);
774
775   sprintf (chvnostr, "%d", chvno);
776   return app->fnc.change_pin (app, NULL, chvnostr, reset,
777                               pin_cb, NULL);
778 }
779
780 /* Perform a CHECKPIN operation.  SERIALNO should be the seriial
781    number of the card - optioanlly followed by the fingerprint;
782    however the fingerprint is ignored here. */
783 int
784 agent_scd_checkpin (const char *serialnobuf)
785 {
786   APP app;
787
788   app = current_app? current_app : open_card ();
789   if (!app)
790     return gpg_error (GPG_ERR_CARD);
791
792   return app->fnc.check_pin (app, serialnobuf, pin_cb, NULL);
793 }
794