* ttyio.c (tty_enable_completion, tty_disable_completion): Enable and
[gnupg.git] / scd / apdu.c
1 /* apdu.c - ISO 7816 APDU functions and low level I/O
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 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <dlfcn.h>
27 #include <assert.h>
28
29 #include "scdaemon.h"
30 #include "apdu.h"
31
32 #define HAVE_CTAPI 1
33
34 #define MAX_READER 4 /* Number of readers we support concurrently. */
35 #define CARD_CONNECT_TIMEOUT 1 /* Number of seconds to wait for
36                                   insertion of the card (1 = don't wait). */
37
38
39
40 /* A global table to keep track of active readers. */
41 static struct {
42   int used;            /* True if slot is used. */
43   unsigned short port; /* port number0 = unused, 1 - dev/tty */
44   int status;
45   unsigned char atr[33];
46   size_t atrlen;
47 } reader_table[MAX_READER];                          
48
49
50 /* ct API function pointer. */
51 static char (*CT_init) (unsigned short ctn, unsigned short Pn);
52 static char (*CT_data) (unsigned short ctn, unsigned char *dad,
53                         unsigned char *sad, unsigned short lc,
54                         unsigned char *cmd, unsigned short *lr,
55                         unsigned char *rsp);
56 static char (*CT_close) (unsigned short ctn);
57
58
59
60
61 \f
62 /* 
63       Helper
64  */
65  
66
67 /* Find an unused reader slot for PORT and put it into the reader
68    table.  Return -1 on error or the index into the reader table. */
69 static int 
70 new_reader_slot (int port)    
71 {
72   int i, reader = -1;
73
74   if (port < 0 || port > 0xffff)
75     {
76       log_error ("new_reader_slot: invalid port %d requested\n", port);
77       return -1;
78     }
79
80   for (i=0; i < MAX_READER; i++)
81     {
82       if (reader_table[i].used && reader_table[i].port == port)
83         {
84           log_error ("new_reader_slot: requested port %d already in use\n",
85                      reader);
86           return -1; 
87         }
88       else if (!reader_table[i].used && reader == -1)
89         reader = i;
90     }
91   if (reader == -1)
92     {
93       log_error ("new_reader_slot: out of slots\n");
94       return -1;
95     }
96   reader_table[reader].used = 1;
97   reader_table[reader].port = port;
98   return reader;
99 }
100
101
102 static void
103 dump_reader_status (int reader)
104 {
105   log_info ("reader %d: %s\n", reader,
106             reader_table[reader].status == 1? "Processor ICC present" :
107             reader_table[reader].status == 0? "Memory ICC present" :
108                                               "ICC not present" );
109  
110   if (reader_table[reader].status != -1)
111     {
112       log_info ("reader %d: ATR=", reader);
113       log_printhex ("", reader_table[reader].atr,
114                     reader_table[reader].atrlen);
115     }
116 }
117
118
119 \f
120 #ifdef HAVE_CTAPI
121 /* 
122        ct API Interface 
123  */
124
125 static const char *
126 ct_error_string (int err)
127 {
128   switch (err)
129     {
130     case 0: return "okay";
131     case -1: return "invalid data";
132     case -8: return "ct error";
133     case -10: return "transmission error";
134     case -11: return "memory allocation error";
135     case -128: return "HTSI error";
136     default: return "unknown CT-API error";
137     }
138 }
139
140 /* Wait for the card in READER and activate it.  Return -1 on error or
141    0 on success. */
142 static int
143 ct_activate_card (int reader)
144 {
145   int rc, count;
146
147   for (count = 0; count < CARD_CONNECT_TIMEOUT; count++)
148     {
149       unsigned char dad[1], sad[1], cmd[11], buf[256];
150       unsigned short buflen;
151
152       if (count)
153         sleep (1); /* FIXME: we should use a more reliable timer. */
154
155       /* Check whether card has been inserted. */
156       dad[0] = 1;     /* Destination address: CT. */    
157       sad[0] = 2;     /* Source address: Host. */
158
159       cmd[0] = 0x20;  /* Class byte. */
160       cmd[1] = 0x13;  /* Request status. */
161       cmd[2] = 0x00;  /* From kernel. */
162       cmd[3] = 0x80;  /* Return card's DO. */
163       cmd[4] = 0x00;
164
165       buflen = DIM(buf);
166
167       rc = CT_data (reader, dad, sad, 5, cmd, &buflen, buf);
168       if (rc || buflen < 2 || buf[buflen-2] != 0x90)
169         {
170           log_error ("ct_activate_card: can't get status of reader %d: %s\n",
171                      reader, ct_error_string (rc));
172           return -1;
173         }
174
175       if (buf[0] == 0x05)
176         { /* Connected, now activate the card. */           
177           dad[0] = 1;    /* Destination address: CT. */    
178           sad[0] = 2;    /* Source address: Host. */
179
180           cmd[0] = 0x20;  /* Class byte. */
181           cmd[1] = 0x12;  /* Request ICC. */
182           cmd[2] = 0x01;  /* From first interface. */
183           cmd[3] = 0x01;  /* Return card's ATR. */
184           cmd[4] = 0x00;
185
186           buflen = DIM(buf);
187
188           rc = CT_data (reader, dad, sad, 5, cmd, &buflen, buf);
189           if (rc || buflen < 2 || buf[buflen-2] != 0x90)
190             {
191               log_error ("ct_activate_card(%d): activation failed: %s\n",
192                          reader, ct_error_string (rc));
193               return -1;
194             }
195
196           /* Store the type and the ATR. */
197           if (buflen - 2 > DIM (reader_table[0].atr))
198             {
199               log_error ("ct_activate_card(%d): ATR too long\n", reader);
200               return -1;
201             }
202
203           reader_table[reader].status = buf[buflen - 1];
204           memcpy (reader_table[reader].atr, buf, buflen - 2);
205           reader_table[reader].atrlen = buflen - 2;
206           return 0;
207         }
208
209     }
210  
211   log_info ("ct_activate_card(%d): timeout waiting for card\n", reader);
212   return -1;
213 }
214
215
216 /* Open a reader and return an internal handle for it.  PORT is a
217    non-negative value with the port number of the reader. USB readers
218    do have port numbers starting at 32769. */
219 static int
220 open_ct_reader (int port)
221 {
222   int rc, reader;
223
224   reader = new_reader_slot (port);
225   if (reader == -1)
226     return reader;
227
228   rc = CT_init (reader, (unsigned short)port);
229   if (rc)
230     {
231       log_error ("apdu_open_ct_reader failed on port %d: %s\n",
232                  port, ct_error_string (rc));
233       reader_table[reader].used = 0;
234       return -1;
235     }
236
237   rc = ct_activate_card (reader);
238   if (rc)
239     {
240       reader_table[reader].used = 0;
241       return -1;
242     }
243
244   dump_reader_status (reader);
245   return reader;
246 }
247
248
249 /* Actually send the APDU of length APDULEN to SLOT and return a
250    maximum of *BUFLEN data in BUFFER, the actual retruned size will be
251    set to BUFLEN.  Returns: CT API error code. */
252 static int
253 ct_send_apdu (int slot, unsigned char *apdu, size_t apdulen,
254               unsigned char *buffer, size_t *buflen)
255 {
256   int rc;
257   unsigned char dad[1], sad[1];
258   unsigned short ctbuflen;
259   
260   dad[0] = 0;     /* Destination address: Card. */    
261   sad[0] = 2;     /* Source address: Host. */
262   ctbuflen = *buflen;
263   if (DBG_CARD_IO)
264     log_printhex ("  CT_data:", apdu, apdulen);
265   rc = CT_data (slot, dad, sad, apdulen, apdu, &ctbuflen, buffer);
266   *buflen = ctbuflen;
267
268   /* FIXME: map the errorcodes to GNUPG ones, so that they can be
269      shared between CTAPI and PCSC. */
270   return rc;
271 }
272
273
274 #endif /*HAVE_CTAPI*/
275
276 \f
277 #ifdef HAVE_PCSC
278 /* 
279        PC/SC Interface
280  */
281
282
283 #endif /*HAVE_PCSC*/
284
285 \f
286 /* 
287        Driver Access
288  */
289
290 /* Open the reader and return an internal slot number or -1 on
291    error. */
292 int
293 apdu_open_reader (int port)
294 {
295   static int ct_api_loaded;
296
297   if (!ct_api_loaded)
298     {
299       void *handle;
300
301       handle = dlopen ("libtowitoko.so", RTLD_LAZY);
302       if (!handle)
303         {
304           log_error ("apdu_open_reader: failed to open driver: %s",
305                      dlerror ());
306           return -1;
307         }
308       CT_init = dlsym (handle, "CT_init");
309       CT_data = dlsym (handle, "CT_data");
310       CT_close = dlsym (handle, "CT_close");
311       if (!CT_init || !CT_data || !CT_close)
312         {
313           log_error ("apdu_open_reader: invalid driver\n");
314           dlclose (handle);
315           return -1;
316         }
317       ct_api_loaded = 1;
318     }
319   return open_ct_reader (port);
320 }
321
322
323 unsigned char *
324 apdu_get_atr (int slot, size_t *atrlen)
325 {
326   char *buf;
327
328   if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used )
329     return NULL;
330   
331   buf = xtrymalloc (reader_table[slot].atrlen);
332   if (!buf)
333     return NULL;
334   memcpy (buf, reader_table[slot].atr, reader_table[slot].atrlen);
335   *atrlen = reader_table[slot].atrlen;
336   return buf;
337 }
338   
339     
340 static const char *
341 error_string (int slot, int rc)
342 {
343 #ifdef HAVE_CTAPI
344   return ct_error_string (rc);
345 #elif defined(HAVE_PCSC)
346   return "?";
347 #else
348   return "?";
349 #endif
350 }
351
352
353 /* Dispatcher for the actual send_apdu fucntion. */
354 static int
355 send_apdu (int slot, unsigned char *apdu, size_t apdulen,
356            unsigned char *buffer, size_t *buflen)
357 {
358 #ifdef HAVE_CTAPI
359   return ct_send_apdu (slot, apdu, apdulen, buffer, buflen);
360 #elif defined(HAVE_PCSC)
361   return SW_HOST_NO_DRIVER;
362 #else
363   return SW_HOST_NO_DRIVER;
364 #endif
365 }
366
367 /* Send an APDU to the card in SLOT.  The APDU is created from all
368    given parameters: CLASS, INS, P0, P1, LC, DATA, LE.  A value of -1
369    for LC won't sent this field and the data field; in this case DATA
370    must also be passed as NULL.  The return value is the status word
371    or -1 for an invalid SLOT or other non card related error.  If
372    RETBUF is not NULL, it will receive an allocated buffer with the
373    returned data.  The length of that data will be put into
374    *RETBUFLEN.  The caller is reponsible for releasing the buffer even
375    in case of errors.  */
376 int 
377 apdu_send_le(int slot, int class, int ins, int p0, int p1,
378              int lc, const char *data, int le,
379              unsigned char **retbuf, size_t *retbuflen)
380 {
381   unsigned char result[256+10]; /* 10 extra in case of bugs in the driver. */
382   size_t resultlen = 256;
383   unsigned char apdu[5+256+1];
384   size_t apdulen;
385   int rc, sw;
386
387   if (DBG_CARD_IO)
388     log_debug ("send apdu: c=%02X i=%02X p0=%02X p1=%02X lc=%d le=%d\n",
389                class, ins, p0, p1, lc, le);
390
391   if (lc != -1 && (lc > 255 || lc < 0))
392     return SW_WRONG_LENGTH; 
393   if (le != -1 && (le > 256 || le < 1))
394     return SW_WRONG_LENGTH; 
395   if ((!data && lc != -1) || (data && lc == -1))
396     return SW_HOST_INV_VALUE;
397
398   apdulen = 0;
399   apdu[apdulen++] = class;
400   apdu[apdulen++] = ins;
401   apdu[apdulen++] = p0;
402   apdu[apdulen++] = p1;
403   if (lc != -1)
404     {
405       apdu[apdulen++] = lc;
406       memcpy (apdu+apdulen, data, lc);
407       apdulen += lc;
408     }
409   if (le != -1)
410     apdu[apdulen++] = le; /* Truncation is okay becuase 0 means 256. */
411   assert (sizeof (apdu) >= apdulen);
412   /* As safeguard don't pass any garbage from the stack to the driver. */
413   memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
414   rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
415   if (rc || resultlen < 2)
416     {
417       log_error ("apdu_send_simple(%d) failed: %s\n",
418                  slot, error_string (slot, rc));
419       return SW_HOST_INCOMPLETE_CARD_RESPONSE;
420     }
421   sw = (result[resultlen-2] << 8) | result[resultlen-1];
422   /* store away the returned data but strip the statusword. */
423   resultlen -= 2;
424   if (DBG_CARD_IO)
425     {
426       log_debug (" response: sw=%04X  datalen=%d\n", sw, resultlen);
427       if ( !retbuf && (sw == SW_SUCCESS || (sw & 0xff00) == SW_MORE_DATA))
428         log_printhex ("     dump: ", result, resultlen);
429     }
430
431   if (sw == SW_SUCCESS)
432     {
433       if (retbuf)
434         {
435           *retbuf = xtrymalloc (resultlen? resultlen : 1);
436           if (!*retbuf)
437             return SW_HOST_OUT_OF_CORE;
438           *retbuflen = resultlen;
439           memcpy (*retbuf, result, resultlen);
440         }
441     }
442   else if ((sw & 0xff00) == SW_MORE_DATA)
443     {
444       unsigned char *p = NULL, *tmp;
445       size_t bufsize = 4096;
446
447       /* It is likely that we need to return much more data, so we
448          start off with a large buffer. */
449       if (retbuf)
450         {
451           *retbuf = p = xtrymalloc (bufsize);
452           if (!*retbuf)
453             return SW_HOST_OUT_OF_CORE;
454           assert (resultlen < bufsize);
455           memcpy (p, result, resultlen);
456           p += resultlen;
457         }
458
459       do
460         {
461           int len = (sw & 0x00ff);
462           
463           log_debug ("apdu_send_simple(%d): %d more bytes available\n",
464                      slot, len);
465           apdulen = 0;
466           apdu[apdulen++] = class;
467           apdu[apdulen++] = 0xC0;
468           apdu[apdulen++] = 0;
469           apdu[apdulen++] = 0;
470           apdu[apdulen++] = 64; /* that is 256 bytes for Le */
471           memset (apdu+apdulen, 0, sizeof (apdu) - apdulen);
472           rc = send_apdu (slot, apdu, apdulen, result, &resultlen);
473           if (rc || resultlen < 2)
474             {
475               log_error ("apdu_send_simple(%d) for get response failed: %s\n",
476                          slot, error_string (slot, rc));
477               return SW_HOST_INCOMPLETE_CARD_RESPONSE;
478             }
479           sw = (result[resultlen-2] << 8) | result[resultlen-1];
480           resultlen -= 2;
481           if (DBG_CARD_IO)
482             {
483               log_debug ("     more: sw=%04X  datalen=%d\n", sw, resultlen);
484               if (!retbuf && (sw==SW_SUCCESS || (sw&0xff00)==SW_MORE_DATA))
485                 log_printhex ("     dump: ", result, resultlen);
486             }
487
488           if ((sw & 0xff00) == SW_MORE_DATA || sw == SW_SUCCESS)
489             {
490               if (retbuf)
491                 {
492                   if (p - *retbuf + resultlen > bufsize)
493                     {
494                       bufsize += resultlen > 4096? resultlen: 4096;
495                       tmp = xtryrealloc (*retbuf, bufsize);
496                       if (!tmp)
497                         return SW_HOST_OUT_OF_CORE;
498                       p = tmp + (p - *retbuf);
499                       *retbuf = tmp;
500                     }
501                   memcpy (p, result, resultlen);
502                   p += resultlen;
503                 }
504             }
505           else
506             log_info ("apdu_send_simple(%d) "
507                       "got unexpected status %04X from get response\n",
508                       slot, sw);
509         }
510       while ((sw & 0xff00) == SW_MORE_DATA);
511       
512       if (retbuf)
513         {
514           *retbuflen = p - *retbuf;
515           tmp = xtryrealloc (*retbuf, *retbuflen);
516           if (tmp)
517             *retbuf = tmp;
518         }
519     }
520   if (DBG_CARD_IO && retbuf && sw == SW_SUCCESS)
521     log_printhex ("      dump: ", *retbuf, *retbuflen);
522  
523   return sw;
524 }
525
526 /* Send an APDU to the card in SLOT.  The APDU is created from all
527    given parameters: CLASS, INS, P0, P1, LC, DATA.  A value of -1 for
528    LC won't sent this field and the data field; in this case DATA must
529    also be passed as NULL. The return value is the status word or -1
530    for an invalid SLOT or other non card related error.  If RETBUF is
531    not NULL, it will receive an allocated buffer with the returned
532    data.  The length of that data will be put into *RETBUFLEN.  The
533    caller is reponsible for releasing the buffer even in case of
534    errors.  */
535 int 
536 apdu_send (int slot, int class, int ins, int p0, int p1,
537            int lc, const char *data, unsigned char **retbuf, size_t *retbuflen)
538 {
539   return apdu_send_le (slot, class, ins, p0, p1, lc, data, 256, 
540                        retbuf, retbuflen);
541 }
542
543 /* Send an APDU to the card in SLOT.  The APDU is created from all
544    given parameters: CLASS, INS, P0, P1, LC, DATA.  A value of -1 for
545    LC won't sent this field and the data field; in this case DATA must
546    also be passed as NULL. The return value is the status word or -1
547    for an invalid SLOT or other non card related error.  No data will be
548    returned. */
549 int 
550 apdu_send_simple (int slot, int class, int ins, int p0, int p1,
551                   int lc, const char *data)
552 {
553   return apdu_send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL);
554 }
555
556
557
558