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