Fixed a couple of problems
[gnupg.git] / g10 / iso7816.c
1 /* iso7816.c - ISO 7816 commands
2  *      Copyright (C) 2003, 2004 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  * $Id$
22  */
23
24 #include <config.h>
25 #include <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #if defined(GNUPG_SCD_MAIN_HEADER)
31 #include GNUPG_SCD_MAIN_HEADER
32 #elif GNUPG_MAJOR_VERSION == 1
33 /* This is used with GnuPG version < 1.9.  The code has been source
34    copied from the current GnuPG >= 1.9  and is maintained over
35    there. */
36 #include "options.h"
37 #include "errors.h"
38 #include "memory.h"
39 #include "util.h"
40 #include "i18n.h"
41 #else /* GNUPG_MAJOR_VERSION != 1 */
42 #include "scdaemon.h"
43 #endif /* GNUPG_MAJOR_VERSION != 1 */
44
45 #include "iso7816.h"
46 #include "apdu.h"
47
48
49 #define CMD_SELECT_FILE 0xA4
50 #define CMD_VERIFY      0x20
51 #define CMD_CHANGE_REFERENCE_DATA 0x24
52 #define CMD_RESET_RETRY_COUNTER   0x2C
53 #define CMD_GET_DATA    0xCA
54 #define CMD_PUT_DATA    0xDA
55 #define CMD_MSE         0x22
56 #define CMD_PSO         0x2A
57 #define CMD_INTERNAL_AUTHENTICATE 0x88
58 #define CMD_GENERATE_KEYPAIR      0x47
59 #define CMD_GET_CHALLENGE         0x84
60 #define CMD_READ_BINARY 0xB0
61 #define CMD_READ_RECORD 0xB2
62
63 static gpg_error_t
64 map_sw (int sw)
65 {
66   gpg_err_code_t ec;
67
68   switch (sw)
69     {
70     case SW_EEPROM_FAILURE: ec = GPG_ERR_HARDWARE; break;
71     case SW_WRONG_LENGTH:   ec = GPG_ERR_INV_VALUE; break;
72     case SW_CHV_WRONG:      ec = GPG_ERR_BAD_PIN; break;
73     case SW_CHV_BLOCKED:    ec = GPG_ERR_PIN_BLOCKED; break;
74     case SW_USE_CONDITIONS: ec = GPG_ERR_USE_CONDITIONS; break;
75     case SW_NOT_SUPPORTED:  ec = GPG_ERR_NOT_SUPPORTED; break;
76     case SW_BAD_PARAMETER:  ec = GPG_ERR_INV_VALUE; break;
77     case SW_FILE_NOT_FOUND: ec = GPG_ERR_ENOENT; break;
78     case SW_RECORD_NOT_FOUND:ec= GPG_ERR_NOT_FOUND; break;
79     case SW_REF_NOT_FOUND:  ec = GPG_ERR_NO_OBJ; break;
80     case SW_BAD_P0_P1:      ec = GPG_ERR_INV_VALUE; break;
81     case SW_EXACT_LENGTH:   ec = GPG_ERR_INV_VALUE; break;
82     case SW_INS_NOT_SUP:    ec = GPG_ERR_CARD; break;
83     case SW_CLA_NOT_SUP:    ec = GPG_ERR_CARD; break;
84     case SW_SUCCESS:        ec = 0; break;
85
86     case SW_HOST_OUT_OF_CORE: ec = GPG_ERR_ENOMEM; break;
87     case SW_HOST_INV_VALUE:   ec = GPG_ERR_INV_VALUE; break;
88     case SW_HOST_INCOMPLETE_CARD_RESPONSE: ec = GPG_ERR_CARD; break;
89     case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break;
90     case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break;
91     case SW_HOST_BUSY:           ec = GPG_ERR_EBUSY; break;
92     case SW_HOST_NO_CARD:        ec = GPG_ERR_CARD_NOT_PRESENT; break;
93     case SW_HOST_CARD_INACTIVE:  ec = GPG_ERR_CARD_RESET; break;
94     case SW_HOST_CARD_IO_ERROR:  ec = GPG_ERR_EIO; break;
95     case SW_HOST_GENERAL_ERROR:  ec = GPG_ERR_GENERAL; break;
96     case SW_HOST_NO_READER:      ec = GPG_ERR_ENODEV; break;
97     case SW_HOST_ABORTED:        ec = GPG_ERR_CANCELED; break;
98
99     default:
100       if ((sw & 0x010000))
101         ec = GPG_ERR_GENERAL; /* Should not happen. */
102       else if ((sw & 0xff00) == SW_MORE_DATA)
103         ec = 0; /* This should actually never been seen here. */
104       else
105         ec = GPG_ERR_CARD;
106     }
107   return gpg_error (ec);
108 }
109
110 /* Map a status word from the APDU layer to a gpg-error code.  */
111 gpg_error_t
112 iso7816_map_sw (int sw)
113 {
114   /* All APDU functions should return 0x9000 on success but for
115      historical reasons of the implementation some return 0 to
116      indicate success.  We allow for that here. */
117   return sw? map_sw (sw) : 0;
118 }
119
120
121 /* This function is specialized version of the SELECT FILE command.
122    SLOT is the card and reader as created for example by
123    apdu_open_reader (), AID is a buffer of size AIDLEN holding the
124    requested application ID.  The function can't be used to enumerate
125    AIDs and won't return the AID on success.  The return value is 0
126    for okay or a GPG error code.  Note that ISO error codes are
127    internally mapped. */
128 gpg_error_t
129 iso7816_select_application (int slot, const char *aid, size_t aidlen)
130 {
131   int sw;
132   sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4, 0, aidlen, aid);
133   return map_sw (sw);
134 }
135
136
137 gpg_error_t
138 iso7816_select_file (int slot, int tag, int is_dir,
139                      unsigned char **result, size_t *resultlen)
140 {
141   int sw, p0, p1;
142   unsigned char tagbuf[2];
143
144   tagbuf[0] = (tag >> 8) & 0xff;
145   tagbuf[1] = tag & 0xff;
146
147   if (result || resultlen)
148     {
149       *result = NULL;
150       *resultlen = 0;
151       return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
152     }
153   else
154     {
155       p0 = (tag == 0x3F00)? 0: is_dir? 1:2;
156       p1 = 0x0c; /* No FC return. */
157       sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE,
158                              p0, p1, 2, (char*)tagbuf );
159       return map_sw (sw);
160     }
161
162   return 0;
163 }
164
165
166 /* Do a select file command with a direct path. */
167 gpg_error_t
168 iso7816_select_path (int slot, const unsigned short *path, size_t pathlen,
169                      unsigned char **result, size_t *resultlen)
170 {
171   int sw, p0, p1;
172   unsigned char buffer[100];
173   int buflen;
174   
175   if (result || resultlen)
176     {
177       *result = NULL;
178       *resultlen = 0;
179       return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
180     }
181   
182   if (pathlen/2 >= sizeof buffer)
183     return gpg_error (GPG_ERR_TOO_LARGE);
184   
185   for (buflen = 0; pathlen; pathlen--, path++)
186     {
187       buffer[buflen++] = (*path >> 8);
188       buffer[buflen++] = *path;
189     }
190
191   p0 = 0x08;
192   p1 = 0x0c; /* No FC return. */
193   sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE,
194                          p0, p1, buflen, (char*)buffer );
195   return map_sw (sw);
196 }
197
198
199 /* This is a private command currently only working for TCOS cards. */
200 gpg_error_t
201 iso7816_list_directory (int slot, int list_dirs,
202                         unsigned char **result, size_t *resultlen)
203 {
204   int sw;
205
206   if (!result || !resultlen)
207     return gpg_error (GPG_ERR_INV_VALUE);
208   *result = NULL;
209   *resultlen = 0;
210
211   sw = apdu_send (slot, 0x80, 0xAA, list_dirs? 1:2, 0, -1, NULL,
212                   result, resultlen);
213   if (sw != SW_SUCCESS)
214     {
215       /* Make sure that pending buffers are released. */
216       xfree (*result);
217       *result = NULL;
218       *resultlen = 0;
219     }
220   return map_sw (sw);
221 }
222
223
224
225 /* Perform a VERIFY command on SLOT using the card holder verification
226    vector CHVNO with a CHV of lenght CHVLEN.  Returns 0 on success. */
227 gpg_error_t
228 iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen)
229 {
230   int sw;
231
232   sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv);
233   return map_sw (sw);
234 }
235
236 /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder
237    verification vector CHVNO.  If the OLDCHV is NULL (and OLDCHVLEN
238    0), a "change reference data" is done, otherwise an "exchange
239    reference data".  The new reference data is expected in NEWCHV of
240    length NEWCHVLEN.  */
241 gpg_error_t
242 iso7816_change_reference_data (int slot, int chvno,
243                                const char *oldchv, size_t oldchvlen,
244                                const char *newchv, size_t newchvlen)
245 {
246   int sw;
247   char *buf;
248
249   if ((!oldchv && oldchvlen)
250       || (oldchv && !oldchvlen)
251       || !newchv || !newchvlen )
252     return gpg_error (GPG_ERR_INV_VALUE);
253
254   buf = xtrymalloc (oldchvlen + newchvlen);
255   if (!buf)
256     return gpg_error (gpg_err_code_from_errno (errno));
257   if (oldchvlen)
258     memcpy (buf, oldchv, oldchvlen);
259   memcpy (buf+oldchvlen, newchv, newchvlen);
260
261   sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA,
262                          oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf);
263   xfree (buf);
264   return map_sw (sw);
265
266 }
267
268 gpg_error_t
269 iso7816_reset_retry_counter (int slot, int chvno,
270                              const char *newchv, size_t newchvlen)
271 {
272   int sw;
273
274   if (!newchv || !newchvlen )
275     return gpg_error (GPG_ERR_INV_VALUE);
276
277   sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER,
278                          2, chvno, newchvlen, newchv);
279   return map_sw (sw);
280 }
281
282
283 /* Perform a GET DATA command requesting TAG and storing the result in
284    a newly allocated buffer at the address passed by RESULT.  Return
285    the length of this data at the address of RESULTLEN. */
286 gpg_error_t
287 iso7816_get_data (int slot, int tag,
288                   unsigned char **result, size_t *resultlen)
289 {
290   int sw;
291
292   if (!result || !resultlen)
293     return gpg_error (GPG_ERR_INV_VALUE);
294   *result = NULL;
295   *resultlen = 0;
296
297   sw = apdu_send (slot, 0x00, CMD_GET_DATA,
298                   ((tag >> 8) & 0xff), (tag & 0xff), -1, NULL,
299                   result, resultlen);
300   if (sw != SW_SUCCESS)
301     {
302       /* Make sure that pending buffers are released. */
303       xfree (*result);
304       *result = NULL;
305       *resultlen = 0;
306       return map_sw (sw);
307     }
308
309   return 0;
310 }
311
312
313 /* Perform a PUT DATA command on card in SLOT.  Write DATA of length
314    DATALEN to TAG. */
315 gpg_error_t
316 iso7816_put_data (int slot, int tag,
317                   const unsigned char *data, size_t datalen)
318 {
319   int sw;
320
321   sw = apdu_send_simple (slot, 0x00, CMD_PUT_DATA,
322                          ((tag >> 8) & 0xff), (tag & 0xff),
323                          datalen, (const char*)data);
324   return map_sw (sw);
325 }
326
327 /* Manage Security Environment.  This is a weird operation and there
328    is no easy abstraction for it.  Furthermore, some card seem to have
329    a different interpreation of 7816-8 and thus we resort to let the
330    caller decide what to do. */
331 gpg_error_t
332 iso7816_manage_security_env (int slot, int p1, int p2,
333                              const unsigned char *data, size_t datalen)
334 {
335   int sw;
336
337   if (p1 < 0 || p1 > 255 || p2 < 0 || p2 > 255 )
338     return gpg_error (GPG_ERR_INV_VALUE);
339
340   sw = apdu_send_simple (slot, 0x00, CMD_MSE, p1, p2, 
341                          data? datalen : -1, (const char*)data);
342   return map_sw (sw);
343 }
344
345
346 /* Perform the security operation COMPUTE DIGITAL SIGANTURE.  On
347    success 0 is returned and the data is availavle in a newly
348    allocated buffer stored at RESULT with its length stored at
349    RESULTLEN. */
350 gpg_error_t
351 iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen,
352                     unsigned char **result, size_t *resultlen)
353 {
354   int sw;
355
356   if (!data || !datalen || !result || !resultlen)
357     return gpg_error (GPG_ERR_INV_VALUE);
358   *result = NULL;
359   *resultlen = 0;
360
361   sw = apdu_send (slot, 0x00, CMD_PSO, 0x9E, 0x9A, datalen, (const char*)data,
362                   result, resultlen);
363   if (sw != SW_SUCCESS)
364     {
365       /* Make sure that pending buffers are released. */
366       xfree (*result);
367       *result = NULL;
368       *resultlen = 0;
369       return map_sw (sw);
370     }
371
372   return 0;
373 }
374
375
376 /* Perform the security operation DECIPHER.  PADIND is the padding
377    indicator to be used.  It should be 0 if no padding is required, a
378    value of -1 suppresses the padding byte.  On success 0 is returned
379    and the plaintext is available in a newly allocated buffer stored
380    at RESULT with its length stored at RESULTLEN. */
381 gpg_error_t
382 iso7816_decipher (int slot, const unsigned char *data, size_t datalen,
383                   int padind, unsigned char **result, size_t *resultlen)
384 {
385   int sw;
386   unsigned char *buf;
387
388   if (!data || !datalen || !result || !resultlen)
389     return gpg_error (GPG_ERR_INV_VALUE);
390   *result = NULL;
391   *resultlen = 0;
392
393   if (padind >= 0)
394     {
395       /* We need to prepend the padding indicator. */
396       buf = xtrymalloc (datalen + 1);
397       if (!buf)
398         return gpg_error (gpg_err_code_from_errno (errno));
399
400       *buf = padind; /* Padding indicator. */
401       memcpy (buf+1, data, datalen);
402       sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86,
403                       datalen+1, (char*)buf,
404                       result, resultlen);
405       xfree (buf);
406     }
407   else
408     {
409       sw = apdu_send (slot, 0x00, CMD_PSO, 0x80, 0x86,
410                       datalen, (const char *)data,
411                       result, resultlen);
412     }
413   if (sw != SW_SUCCESS)
414     {
415       /* Make sure that pending buffers are released. */
416       xfree (*result);
417       *result = NULL;
418       *resultlen = 0;
419       return map_sw (sw);
420     }
421
422   return 0;
423 }
424
425
426 gpg_error_t
427 iso7816_internal_authenticate (int slot,
428                                const unsigned char *data, size_t datalen,
429                                unsigned char **result, size_t *resultlen)
430 {
431   int sw;
432
433   if (!data || !datalen || !result || !resultlen)
434     return gpg_error (GPG_ERR_INV_VALUE);
435   *result = NULL;
436   *resultlen = 0;
437
438   sw = apdu_send (slot, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0,
439                   datalen, (const char*)data,  result, resultlen);
440   if (sw != SW_SUCCESS)
441     {
442       /* Make sure that pending buffers are released. */
443       xfree (*result);
444       *result = NULL;
445       *resultlen = 0;
446       return map_sw (sw);
447     }
448
449   return 0;
450 }
451
452
453 static gpg_error_t
454 do_generate_keypair (int slot, int readonly,
455                   const unsigned char *data, size_t datalen,
456                   unsigned char **result, size_t *resultlen)
457 {
458   int sw;
459
460   if (!data || !datalen || !result || !resultlen)
461     return gpg_error (GPG_ERR_INV_VALUE);
462   *result = NULL;
463   *resultlen = 0;
464
465   sw = apdu_send (slot, 0x00, CMD_GENERATE_KEYPAIR, readonly? 0x81:0x80, 0,
466                   datalen, (const char*)data,  result, resultlen);
467   if (sw != SW_SUCCESS)
468     {
469       /* Make sure that pending buffers are released. */
470       xfree (*result);
471       *result = NULL;
472       *resultlen = 0;
473       return map_sw (sw);
474     }
475
476   return 0;
477 }
478
479
480 gpg_error_t
481 iso7816_generate_keypair (int slot,
482                           const unsigned char *data, size_t datalen,
483                           unsigned char **result, size_t *resultlen)
484 {
485   return do_generate_keypair (slot, 0, data, datalen, result, resultlen);
486 }
487
488
489 gpg_error_t
490 iso7816_read_public_key (int slot,
491                           const unsigned char *data, size_t datalen,
492                           unsigned char **result, size_t *resultlen)
493 {
494   return do_generate_keypair (slot, 1, data, datalen, result, resultlen);
495 }
496
497
498
499 gpg_error_t
500 iso7816_get_challenge (int slot, int length, unsigned char *buffer)
501 {
502   int sw;
503   unsigned char *result;
504   size_t resultlen, n;
505
506   if (!buffer || length < 1)
507     return gpg_error (GPG_ERR_INV_VALUE);
508
509   do
510     {
511       result = NULL;
512       n = length > 254? 254 : length;
513       sw = apdu_send_le (slot, 0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL,
514                          n,
515                          &result, &resultlen);
516       if (sw != SW_SUCCESS)
517         {
518           /* Make sure that pending buffers are released. */
519           xfree (result);
520           return map_sw (sw);
521         }
522       if (resultlen > n)
523         resultlen = n;
524       memcpy (buffer, result, resultlen);
525       buffer += resultlen;
526       length -= resultlen;
527       xfree (result);
528     }
529   while (length > 0);
530
531   return 0;
532 }
533
534 /* Perform a READ BINARY command requesting a maximum of NMAX bytes
535    from OFFSET.  With NMAX = 0 the entire file is read. The result is
536    stored in a newly allocated buffer at the address passed by RESULT.
537    Returns the length of this data at the address of RESULTLEN. */
538 gpg_error_t
539 iso7816_read_binary (int slot, size_t offset, size_t nmax,
540                      unsigned char **result, size_t *resultlen)
541 {
542   int sw;
543   unsigned char *buffer;
544   size_t bufferlen;
545   int read_all = !nmax;
546   size_t n;
547
548   if (!result || !resultlen)
549     return gpg_error (GPG_ERR_INV_VALUE);
550   *result = NULL;
551   *resultlen = 0;
552
553   /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
554      we check for this limit. */
555   if (offset > 32767)
556     return gpg_error (GPG_ERR_INV_VALUE);
557
558   do
559     {
560       buffer = NULL;
561       bufferlen = 0;
562       /* Note, that we to set N to 254 due to problems either with the
563          ccid driver or some TCOS cards.  It actually should be 0
564          which is the official ISO value to read a variable length
565          object. */
566       if (read_all || nmax > 254)
567         n = 254;
568       else
569         n = nmax;
570       sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY,
571                          ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
572                          n, &buffer, &bufferlen);
573       if ( SW_EXACT_LENGTH_P(sw) )
574         {
575           n = (sw & 0x00ff);
576           sw = apdu_send_le (slot, 0x00, CMD_READ_BINARY,
577                              ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
578                              n, &buffer, &bufferlen);
579         }
580
581       if (*result && sw == SW_BAD_P0_P1)
582         {
583           /* Bad Parameter means that the offset is outside of the
584              EF. When reading all data we take this as an indication
585              for EOF.  */
586           break;
587         }
588
589       if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)
590         {
591           /* Make sure that pending buffers are released. */
592           xfree (buffer);
593           xfree (*result);
594           *result = NULL;
595           *resultlen = 0;
596           return map_sw (sw);
597         }
598       if (*result) /* Need to extend the buffer. */
599         {
600           unsigned char *p = xtryrealloc (*result, *resultlen + bufferlen);
601           if (!p)
602             {
603               gpg_error_t err = gpg_error_from_errno (errno);
604               xfree (buffer);
605               xfree (*result);
606               *result = NULL;
607               *resultlen = 0;
608               return err;
609             }
610           *result = p;
611           memcpy (*result + *resultlen, buffer, bufferlen);
612           *resultlen += bufferlen;
613           xfree (buffer);
614           buffer = NULL;
615         }
616       else /* Transfer the buffer into our result. */
617         {
618           *result = buffer;
619           *resultlen = bufferlen;
620         }
621       offset += bufferlen;
622       if (offset > 32767)
623         break; /* We simply truncate the result for too large
624                   files. */
625       if (nmax > bufferlen)
626         nmax -= bufferlen;
627       else
628         nmax = 0;
629     }
630   while ((read_all && sw != SW_EOF_REACHED) || (!read_all && nmax));
631   
632   return 0;
633 }
634
635 /* Perform a READ RECORD command. RECNO gives the record number to
636    read with 0 indicating the current record.  RECCOUNT must be 1 (not
637    all cards support reading of more than one record).  SHORT_EF
638    should be 0 to read the current EF or contain a short EF. The
639    result is stored in a newly allocated buffer at the address passed
640    by RESULT.  Returns the length of this data at the address of
641    RESULTLEN. */
642 gpg_error_t
643 iso7816_read_record (int slot, int recno, int reccount, int short_ef,
644                      unsigned char **result, size_t *resultlen)
645 {
646   int sw;
647   unsigned char *buffer;
648   size_t bufferlen;
649
650   if (!result || !resultlen)
651     return gpg_error (GPG_ERR_INV_VALUE);
652   *result = NULL;
653   *resultlen = 0;
654
655   /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
656      we check for this limit. */
657   if (recno < 0 || recno > 255 || reccount != 1
658       || short_ef < 0 || short_ef > 254 )
659     return gpg_error (GPG_ERR_INV_VALUE);
660
661   buffer = NULL;
662   bufferlen = 0;
663   /* Fixme: Either the ccid driver or the TCOS cards have problems
664      with an Le of 0. */
665   sw = apdu_send_le (slot, 0x00, CMD_READ_RECORD,
666                      recno, 
667                      short_ef? short_ef : 0x04,
668                      -1, NULL,
669                      254, &buffer, &bufferlen);
670
671   if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)
672     {
673       /* Make sure that pending buffers are released. */
674       xfree (buffer);
675       xfree (*result);
676       *result = NULL;
677       *resultlen = 0;
678       return map_sw (sw);
679     }
680   *result = buffer;
681   *resultlen = bufferlen;
682   
683   return 0;
684 }
685