scd: Add two variants to the set of ISO7816 functions.
[gnupg.git] / scd / iso7816.c
1 /* iso7816.c - ISO 7816 commands
2  * Copyright (C) 2003, 2004, 2008, 2009 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 3 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, see <https://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25
26 #if defined(GNUPG_SCD_MAIN_HEADER)
27 #include GNUPG_SCD_MAIN_HEADER
28 #elif GNUPG_MAJOR_VERSION == 1
29 /* This is used with GnuPG version < 1.9.  The code has been source
30    copied from the current GnuPG >= 1.9  and is maintained over
31    there. */
32 #include "options.h"
33 #include "errors.h"
34 #include "memory.h"
35 #include "../common/util.h"
36 #include "../common/i18n.h"
37 #else /* GNUPG_MAJOR_VERSION != 1 */
38 #include "scdaemon.h"
39 #endif /* GNUPG_MAJOR_VERSION != 1 */
40
41 #include "iso7816.h"
42 #include "apdu.h"
43
44
45 #define CMD_SELECT_FILE 0xA4
46 #define CMD_VERIFY                ISO7816_VERIFY
47 #define CMD_CHANGE_REFERENCE_DATA ISO7816_CHANGE_REFERENCE_DATA
48 #define CMD_RESET_RETRY_COUNTER   ISO7816_RESET_RETRY_COUNTER
49 #define CMD_GET_DATA    0xCA
50 #define CMD_PUT_DATA    0xDA
51 #define CMD_MSE         0x22
52 #define CMD_PSO         0x2A
53 #define CMD_INTERNAL_AUTHENTICATE 0x88
54 #define CMD_GENERATE_KEYPAIR      0x47
55 #define CMD_GET_CHALLENGE         0x84
56 #define CMD_READ_BINARY 0xB0
57 #define CMD_READ_RECORD 0xB2
58
59 static gpg_error_t
60 map_sw (int sw)
61 {
62   gpg_err_code_t ec;
63
64   switch (sw)
65     {
66     case SW_EEPROM_FAILURE: ec = GPG_ERR_HARDWARE; break;
67     case SW_TERM_STATE:     ec = GPG_ERR_OBJ_TERM_STATE; break;
68     case SW_WRONG_LENGTH:   ec = GPG_ERR_INV_VALUE; break;
69     case SW_SM_NOT_SUP:     ec = GPG_ERR_NOT_SUPPORTED; break;
70     case SW_CC_NOT_SUP:     ec = GPG_ERR_NOT_SUPPORTED; break;
71     case SW_CHV_WRONG:      ec = GPG_ERR_BAD_PIN; break;
72     case SW_CHV_BLOCKED:    ec = GPG_ERR_PIN_BLOCKED; break;
73     case SW_USE_CONDITIONS: ec = GPG_ERR_USE_CONDITIONS; break;
74     case SW_NOT_SUPPORTED:  ec = GPG_ERR_NOT_SUPPORTED; break;
75     case SW_BAD_PARAMETER:  ec = GPG_ERR_INV_VALUE; break;
76     case SW_FILE_NOT_FOUND: ec = GPG_ERR_ENOENT; break;
77     case SW_RECORD_NOT_FOUND:ec= GPG_ERR_NOT_FOUND; break;
78     case SW_REF_NOT_FOUND:  ec = GPG_ERR_NO_OBJ; break;
79     case SW_BAD_P0_P1:      ec = GPG_ERR_INV_VALUE; break;
80     case SW_EXACT_LENGTH:   ec = GPG_ERR_INV_VALUE; break;
81     case SW_INS_NOT_SUP:    ec = GPG_ERR_CARD; break;
82     case SW_CLA_NOT_SUP:    ec = GPG_ERR_CARD; break;
83     case SW_SUCCESS:        ec = 0; break;
84
85     case SW_HOST_OUT_OF_CORE: ec = GPG_ERR_ENOMEM; break;
86     case SW_HOST_INV_VALUE:   ec = GPG_ERR_INV_VALUE; break;
87     case SW_HOST_INCOMPLETE_CARD_RESPONSE: ec = GPG_ERR_CARD; break;
88     case SW_HOST_NOT_SUPPORTED: ec = GPG_ERR_NOT_SUPPORTED; break;
89     case SW_HOST_LOCKING_FAILED: ec = GPG_ERR_BUG; break;
90     case SW_HOST_BUSY:           ec = GPG_ERR_EBUSY; break;
91     case SW_HOST_NO_CARD:        ec = GPG_ERR_CARD_NOT_PRESENT; break;
92     case SW_HOST_CARD_INACTIVE:  ec = GPG_ERR_CARD_RESET; break;
93     case SW_HOST_CARD_IO_ERROR:  ec = GPG_ERR_EIO; break;
94     case SW_HOST_GENERAL_ERROR:  ec = GPG_ERR_GENERAL; break;
95     case SW_HOST_NO_READER:      ec = GPG_ERR_ENODEV; break;
96     case SW_HOST_ABORTED:        ec = GPG_ERR_INV_RESPONSE; break;
97     case SW_HOST_NO_PINPAD:      ec = GPG_ERR_NOT_SUPPORTED; break;
98     case SW_HOST_CANCELLED:      ec = GPG_ERR_CANCELED; break;
99
100     default:
101       if ((sw & 0x010000))
102         ec = GPG_ERR_GENERAL; /* Should not happen. */
103       else if ((sw & 0xff00) == SW_MORE_DATA)
104         ec = 0; /* This should actually never been seen here. */
105       else
106         ec = GPG_ERR_CARD;
107     }
108   return gpg_error (ec);
109 }
110
111 /* Map a status word from the APDU layer to a gpg-error code.  */
112 gpg_error_t
113 iso7816_map_sw (int sw)
114 {
115   /* All APDU functions should return 0x9000 on success but for
116      historical reasons of the implementation some return 0 to
117      indicate success.  We allow for that here. */
118   return sw? map_sw (sw) : 0;
119 }
120
121
122 /* This function is specialized version of the SELECT FILE command.
123    SLOT is the card and reader as created for example by
124    apdu_open_reader (), AID is a buffer of size AIDLEN holding the
125    requested application ID.  The function can't be used to enumerate
126    AIDs and won't return the AID on success.  The return value is 0
127    for okay or a GPG error code.  Note that ISO error codes are
128    internally mapped.  Bit 0 of FLAGS should be set if the card does
129    not understand P2=0xC0. */
130 gpg_error_t
131 iso7816_select_application (int slot, const char *aid, size_t aidlen,
132                             unsigned int flags)
133 {
134   int sw;
135   sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE, 4,
136                          (flags&1)? 0 :0x0c, aidlen, aid);
137   return map_sw (sw);
138 }
139
140
141 /* This is the same as iso7816_select_application but may return data
142  * at RESULT,RESULTLEN).  */
143 gpg_error_t
144 iso7816_select_application_ext (int slot, const char *aid, size_t aidlen,
145                                 unsigned int flags,
146                                 unsigned char **result, size_t *resultlen)
147 {
148   int sw;
149   sw = apdu_send (slot, 0, 0x00, CMD_SELECT_FILE, 4,
150                   (flags&1)? 0:0x0c, aidlen, aid,
151                   result, resultlen);
152   return map_sw (sw);
153 }
154
155
156 gpg_error_t
157 iso7816_select_file (int slot, int tag, int is_dir)
158 {
159   int sw, p0, p1;
160   unsigned char tagbuf[2];
161
162   tagbuf[0] = (tag >> 8) & 0xff;
163   tagbuf[1] = tag & 0xff;
164
165   p0 = (tag == 0x3F00)? 0: is_dir? 1:2;
166   p1 = 0x0c; /* No FC return. */
167   sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE,
168                          p0, p1, 2, (char*)tagbuf );
169   return map_sw (sw);
170 }
171
172
173 /* Do a select file command with a direct path. */
174 gpg_error_t
175 iso7816_select_path (int slot, const unsigned short *path, size_t pathlen)
176 {
177   int sw, p0, p1;
178   unsigned char buffer[100];
179   int buflen;
180
181   if (pathlen/2 >= sizeof buffer)
182     return gpg_error (GPG_ERR_TOO_LARGE);
183
184   for (buflen = 0; pathlen; pathlen--, path++)
185     {
186       buffer[buflen++] = (*path >> 8);
187       buffer[buflen++] = *path;
188     }
189
190   p0 = 0x08;
191   p1 = 0x0c; /* No FC return. */
192   sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE,
193                          p0, p1, buflen, (char*)buffer );
194   return map_sw (sw);
195 }
196
197
198 /* This is a private command currently only working for TCOS cards. */
199 gpg_error_t
200 iso7816_list_directory (int slot, int list_dirs,
201                         unsigned char **result, size_t *resultlen)
202 {
203   int sw;
204
205   if (!result || !resultlen)
206     return gpg_error (GPG_ERR_INV_VALUE);
207   *result = NULL;
208   *resultlen = 0;
209
210   sw = apdu_send (slot, 0, 0x80, 0xAA, list_dirs? 1:2, 0, -1, NULL,
211                   result, resultlen);
212   if (sw != SW_SUCCESS)
213     {
214       /* Make sure that pending buffers are released. */
215       xfree (*result);
216       *result = NULL;
217       *resultlen = 0;
218     }
219   return map_sw (sw);
220 }
221
222
223 /* This function sends an already formatted APDU to the card.  With
224    HANDLE_MORE set to true a MORE DATA status will be handled
225    internally.  The return value is a gpg error code (i.e. a mapped
226    status word).  This is basically the same as apdu_send_direct but
227    it maps the status word and does not return it in the result
228    buffer.  */
229 gpg_error_t
230 iso7816_apdu_direct (int slot, const void *apdudata, size_t apdudatalen,
231                      int handle_more,
232                      unsigned char **result, size_t *resultlen)
233 {
234   int sw;
235
236   if (!result || !resultlen)
237     return gpg_error (GPG_ERR_INV_VALUE);
238   *result = NULL;
239   *resultlen = 0;
240
241   sw = apdu_send_direct (slot, 0, apdudata, apdudatalen, handle_more,
242                          result, resultlen);
243   if (!sw)
244     {
245       if (*resultlen < 2)
246         sw = SW_HOST_GENERAL_ERROR;
247       else
248         {
249           sw = ((*result)[*resultlen-2] << 8) | (*result)[*resultlen-1];
250           (*resultlen)--;
251           (*resultlen)--;
252         }
253     }
254   if (sw != SW_SUCCESS)
255     {
256       /* Make sure that pending buffers are released. */
257       xfree (*result);
258       *result = NULL;
259       *resultlen = 0;
260     }
261   return map_sw (sw);
262 }
263
264
265 /* Check whether the reader supports the ISO command code COMMAND on
266    the pinpad.  Returns 0 on success.  */
267 gpg_error_t
268 iso7816_check_pinpad (int slot, int command, pininfo_t *pininfo)
269 {
270   int sw;
271
272   sw = apdu_check_pinpad (slot, command, pininfo);
273   return iso7816_map_sw (sw);
274 }
275
276
277 /* Perform a VERIFY command on SLOT using the card holder verification
278    vector CHVNO.  With PININFO non-NULL the pinpad of the reader will
279    be used.  Returns 0 on success. */
280 gpg_error_t
281 iso7816_verify_kp (int slot, int chvno, pininfo_t *pininfo)
282 {
283   int sw;
284
285   sw = apdu_pinpad_verify (slot, 0x00, CMD_VERIFY, 0, chvno, pininfo);
286   return map_sw (sw);
287 }
288
289 /* Perform a VERIFY command on SLOT using the card holder verification
290    vector CHVNO with a CHV of length CHVLEN.  Returns 0 on success. */
291 gpg_error_t
292 iso7816_verify (int slot, int chvno, const char *chv, size_t chvlen)
293 {
294   int sw;
295
296   sw = apdu_send_simple (slot, 0, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv);
297   return map_sw (sw);
298 }
299
300 /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder
301    verification vector CHVNO.  With PININFO non-NULL the pinpad of the
302    reader will be used.  If IS_EXCHANGE is 0, a "change reference
303    data" is done, otherwise an "exchange reference data".  */
304 gpg_error_t
305 iso7816_change_reference_data_kp (int slot, int chvno, int is_exchange,
306                                   pininfo_t *pininfo)
307 {
308   int sw;
309
310   sw = apdu_pinpad_modify (slot, 0x00, CMD_CHANGE_REFERENCE_DATA,
311                            is_exchange ? 1 : 0, chvno, pininfo);
312   return map_sw (sw);
313 }
314
315 /* Perform a CHANGE_REFERENCE_DATA command on SLOT for the card holder
316    verification vector CHVNO.  If the OLDCHV is NULL (and OLDCHVLEN
317    0), a "change reference data" is done, otherwise an "exchange
318    reference data".  The new reference data is expected in NEWCHV of
319    length NEWCHVLEN.  */
320 gpg_error_t
321 iso7816_change_reference_data (int slot, int chvno,
322                                const char *oldchv, size_t oldchvlen,
323                                const char *newchv, size_t newchvlen)
324 {
325   int sw;
326   char *buf;
327
328   if ((!oldchv && oldchvlen)
329       || (oldchv && !oldchvlen)
330       || !newchv || !newchvlen )
331     return gpg_error (GPG_ERR_INV_VALUE);
332
333   buf = xtrymalloc (oldchvlen + newchvlen);
334   if (!buf)
335     return gpg_error (gpg_err_code_from_errno (errno));
336   if (oldchvlen)
337     memcpy (buf, oldchv, oldchvlen);
338   memcpy (buf+oldchvlen, newchv, newchvlen);
339
340   sw = apdu_send_simple (slot, 0, 0x00, CMD_CHANGE_REFERENCE_DATA,
341                          oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf);
342   xfree (buf);
343   return map_sw (sw);
344
345 }
346
347
348 gpg_error_t
349 iso7816_reset_retry_counter_with_rc (int slot, int chvno,
350                                      const char *data, size_t datalen)
351 {
352   int sw;
353
354   if (!data || !datalen )
355     return gpg_error (GPG_ERR_INV_VALUE);
356
357   sw = apdu_send_simple (slot, 0, 0x00, CMD_RESET_RETRY_COUNTER,
358                          0, chvno, datalen, data);
359   return map_sw (sw);
360 }
361
362
363 gpg_error_t
364 iso7816_reset_retry_counter (int slot, int chvno,
365                              const char *newchv, size_t newchvlen)
366 {
367   int sw;
368
369   sw = apdu_send_simple (slot, 0, 0x00, CMD_RESET_RETRY_COUNTER,
370                          2, chvno, newchvlen, newchv);
371   return map_sw (sw);
372 }
373
374
375
376 /* Perform a GET DATA command requesting TAG and storing the result in
377    a newly allocated buffer at the address passed by RESULT.  Return
378    the length of this data at the address of RESULTLEN. */
379 gpg_error_t
380 iso7816_get_data (int slot, int extended_mode, int tag,
381                   unsigned char **result, size_t *resultlen)
382 {
383   int sw;
384   int le;
385
386   if (!result || !resultlen)
387     return gpg_error (GPG_ERR_INV_VALUE);
388   *result = NULL;
389   *resultlen = 0;
390
391   if (extended_mode > 0 && extended_mode < 256)
392     le = 65534; /* Not 65535 in case it is used as some special flag.  */
393   else if (extended_mode > 0)
394     le = extended_mode;
395   else
396     le = 256;
397
398   sw = apdu_send_le (slot, extended_mode, 0x00, CMD_GET_DATA,
399                      ((tag >> 8) & 0xff), (tag & 0xff), -1, NULL, le,
400                      result, resultlen);
401   if (sw != SW_SUCCESS)
402     {
403       /* Make sure that pending buffers are released. */
404       xfree (*result);
405       *result = NULL;
406       *resultlen = 0;
407       return map_sw (sw);
408     }
409
410   return 0;
411 }
412
413
414 /* Perform a GET DATA command requesting TAG and storing the result in
415  * a newly allocated buffer at the address passed by RESULT.  Return
416  * the length of this data at the address of RESULTLEN.  This variant
417  * is needed for long (3 octet) tags. */
418 gpg_error_t
419 iso7816_get_data_odd (int slot, int extended_mode, unsigned int tag,
420                       unsigned char **result, size_t *resultlen)
421 {
422   int sw;
423   int le;
424   int datalen;
425   unsigned char data[5];
426
427   if (!result || !resultlen)
428     return gpg_error (GPG_ERR_INV_VALUE);
429   *result = NULL;
430   *resultlen = 0;
431
432   if (extended_mode > 0 && extended_mode < 256)
433     le = 65534; /* Not 65535 in case it is used as some special flag.  */
434   else if (extended_mode > 0)
435     le = extended_mode;
436   else
437     le = 256;
438
439   data[0] = 0x5c;
440   if (tag <= 0xff)
441     {
442       data[1] = 1;
443       data[2] = tag;
444       datalen = 3;
445     }
446   else if (tag <= 0xffff)
447     {
448       data[1] = 2;
449       data[2] = (tag >> 8);
450       data[3] = tag;
451       datalen = 4;
452     }
453   else
454     {
455       data[1] = 3;
456       data[2] = (tag >> 16);
457       data[3] = (tag >> 8);
458       data[4] = tag;
459       datalen = 5;
460     }
461
462   sw = apdu_send_le (slot, extended_mode, 0x00, CMD_GET_DATA + 1,
463                      0x3f, 0xff, datalen, data, le,
464                      result, resultlen);
465   if (sw != SW_SUCCESS)
466     {
467       /* Make sure that pending buffers are released. */
468       xfree (*result);
469       *result = NULL;
470       *resultlen = 0;
471       return map_sw (sw);
472     }
473
474   return 0;
475 }
476
477
478 /* Perform a PUT DATA command on card in SLOT.  Write DATA of length
479    DATALEN to TAG.  EXTENDED_MODE controls whether extended length
480    headers or command chaining is used instead of single length
481    bytes. */
482 gpg_error_t
483 iso7816_put_data (int slot, int extended_mode, int tag,
484                   const void *data, size_t datalen)
485 {
486   int sw;
487
488   sw = apdu_send_simple (slot, extended_mode, 0x00, CMD_PUT_DATA,
489                          ((tag >> 8) & 0xff), (tag & 0xff),
490                          datalen, (const char*)data);
491   return map_sw (sw);
492 }
493
494 /* Same as iso7816_put_data but uses an odd instruction byte.  */
495 gpg_error_t
496 iso7816_put_data_odd (int slot, int extended_mode, int tag,
497                       const void *data, size_t datalen)
498 {
499   int sw;
500
501   sw = apdu_send_simple (slot, extended_mode, 0x00, CMD_PUT_DATA+1,
502                          ((tag >> 8) & 0xff), (tag & 0xff),
503                          datalen, (const char*)data);
504   return map_sw (sw);
505 }
506
507 /* Manage Security Environment.  This is a weird operation and there
508    is no easy abstraction for it.  Furthermore, some card seem to have
509    a different interpretation of 7816-8 and thus we resort to let the
510    caller decide what to do. */
511 gpg_error_t
512 iso7816_manage_security_env (int slot, int p1, int p2,
513                              const unsigned char *data, size_t datalen)
514 {
515   int sw;
516
517   if (p1 < 0 || p1 > 255 || p2 < 0 || p2 > 255 )
518     return gpg_error (GPG_ERR_INV_VALUE);
519
520   sw = apdu_send_simple (slot, 0, 0x00, CMD_MSE, p1, p2,
521                          data? datalen : -1, (const char*)data);
522   return map_sw (sw);
523 }
524
525
526 /* Perform the security operation COMPUTE DIGITAL SIGANTURE.  On
527    success 0 is returned and the data is available in a newly
528    allocated buffer stored at RESULT with its length stored at
529    RESULTLEN.  For LE see do_generate_keypair. */
530 gpg_error_t
531 iso7816_compute_ds (int slot, int extended_mode,
532                     const unsigned char *data, size_t datalen, int le,
533                     unsigned char **result, size_t *resultlen)
534 {
535   int sw;
536
537   if (!data || !datalen || !result || !resultlen)
538     return gpg_error (GPG_ERR_INV_VALUE);
539   *result = NULL;
540   *resultlen = 0;
541
542   if (!extended_mode)
543     le = 256;  /* Ignore provided Le and use what apdu_send uses. */
544   else if (le >= 0 && le < 256)
545     le = 256;
546
547   sw = apdu_send_le (slot, extended_mode,
548                      0x00, CMD_PSO, 0x9E, 0x9A,
549                      datalen, (const char*)data,
550                      le,
551                      result, resultlen);
552   if (sw != SW_SUCCESS)
553     {
554       /* Make sure that pending buffers are released. */
555       xfree (*result);
556       *result = NULL;
557       *resultlen = 0;
558       return map_sw (sw);
559     }
560
561   return 0;
562 }
563
564
565 /* Perform the security operation DECIPHER.  PADIND is the padding
566    indicator to be used.  It should be 0 if no padding is required, a
567    value of -1 suppresses the padding byte.  On success 0 is returned
568    and the plaintext is available in a newly allocated buffer stored
569    at RESULT with its length stored at RESULTLEN.  For LE see
570    do_generate_keypair. */
571 gpg_error_t
572 iso7816_decipher (int slot, int extended_mode,
573                   const unsigned char *data, size_t datalen, int le,
574                   int padind, unsigned char **result, size_t *resultlen)
575 {
576   int sw;
577   unsigned char *buf;
578
579   if (!data || !datalen || !result || !resultlen)
580     return gpg_error (GPG_ERR_INV_VALUE);
581   *result = NULL;
582   *resultlen = 0;
583
584   if (!extended_mode)
585     le = 256;  /* Ignore provided Le and use what apdu_send uses. */
586   else if (le >= 0 && le < 256)
587     le = 256;
588
589   if (padind >= 0)
590     {
591       /* We need to prepend the padding indicator. */
592       buf = xtrymalloc (datalen + 1);
593       if (!buf)
594         return gpg_error (gpg_err_code_from_errno (errno));
595
596       *buf = padind; /* Padding indicator. */
597       memcpy (buf+1, data, datalen);
598       sw = apdu_send_le (slot, extended_mode,
599                          0x00, CMD_PSO, 0x80, 0x86,
600                          datalen+1, (char*)buf, le,
601                          result, resultlen);
602       xfree (buf);
603     }
604   else
605     {
606       sw = apdu_send_le (slot, extended_mode,
607                          0x00, CMD_PSO, 0x80, 0x86,
608                          datalen, (const char *)data, le,
609                          result, resultlen);
610     }
611   if (sw != SW_SUCCESS)
612     {
613       /* Make sure that pending buffers are released. */
614       xfree (*result);
615       *result = NULL;
616       *resultlen = 0;
617       return map_sw (sw);
618     }
619
620   return 0;
621 }
622
623
624 /*  For LE see do_generate_keypair.  */
625 gpg_error_t
626 iso7816_internal_authenticate (int slot, int extended_mode,
627                                const unsigned char *data, size_t datalen,
628                                int le,
629                                unsigned char **result, size_t *resultlen)
630 {
631   int sw;
632
633   if (!data || !datalen || !result || !resultlen)
634     return gpg_error (GPG_ERR_INV_VALUE);
635   *result = NULL;
636   *resultlen = 0;
637
638   if (!extended_mode)
639     le = 256;  /* Ignore provided Le and use what apdu_send uses. */
640   else if (le >= 0 && le < 256)
641     le = 256;
642
643   sw = apdu_send_le (slot, extended_mode,
644                      0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0,
645                      datalen, (const char*)data,
646                      le,
647                      result, resultlen);
648   if (sw != SW_SUCCESS)
649     {
650       /* Make sure that pending buffers are released. */
651       xfree (*result);
652       *result = NULL;
653       *resultlen = 0;
654       return map_sw (sw);
655     }
656
657   return 0;
658 }
659
660
661 /* LE is the expected return length.  This is usually 0 except if
662    extended length mode is used and more than 256 byte will be
663    returned.  In that case a value of -1 uses a large default
664    (e.g. 4096 bytes), a value larger 256 used that value.  */
665 static gpg_error_t
666 do_generate_keypair (int slot, int extended_mode, int read_only,
667                      const char *data, size_t datalen, int le,
668                      unsigned char **result, size_t *resultlen)
669 {
670   int sw;
671
672   if (!data || !datalen || !result || !resultlen)
673     return gpg_error (GPG_ERR_INV_VALUE);
674   *result = NULL;
675   *resultlen = 0;
676
677   sw = apdu_send_le (slot, extended_mode,
678                      0x00, CMD_GENERATE_KEYPAIR, read_only? 0x81:0x80, 0,
679                      datalen, data,
680                      le >= 0 && le < 256? 256:le,
681                      result, resultlen);
682   if (sw != SW_SUCCESS)
683     {
684       /* Make sure that pending buffers are released. */
685       xfree (*result);
686       *result = NULL;
687       *resultlen = 0;
688       return map_sw (sw);
689     }
690
691   return 0;
692 }
693
694
695 gpg_error_t
696 iso7816_generate_keypair (int slot, int extended_mode,
697                           const char *data, size_t datalen,
698                           int le,
699                           unsigned char **result, size_t *resultlen)
700 {
701   return do_generate_keypair (slot, extended_mode, 0,
702                               data, datalen, le, result, resultlen);
703 }
704
705
706 gpg_error_t
707 iso7816_read_public_key (int slot, int extended_mode,
708                          const char *data, size_t datalen,
709                          int le,
710                          unsigned char **result, size_t *resultlen)
711 {
712   return do_generate_keypair (slot, extended_mode, 1,
713                               data, datalen, le, result, resultlen);
714 }
715
716
717
718 gpg_error_t
719 iso7816_get_challenge (int slot, int length, unsigned char *buffer)
720 {
721   int sw;
722   unsigned char *result;
723   size_t resultlen, n;
724
725   if (!buffer || length < 1)
726     return gpg_error (GPG_ERR_INV_VALUE);
727
728   do
729     {
730       result = NULL;
731       n = length > 254? 254 : length;
732       sw = apdu_send_le (slot, 0,
733                          0x00, CMD_GET_CHALLENGE, 0, 0, -1, NULL, n,
734                          &result, &resultlen);
735       if (sw != SW_SUCCESS)
736         {
737           /* Make sure that pending buffers are released. */
738           xfree (result);
739           return map_sw (sw);
740         }
741       if (resultlen > n)
742         resultlen = n;
743       memcpy (buffer, result, resultlen);
744       buffer += resultlen;
745       length -= resultlen;
746       xfree (result);
747     }
748   while (length > 0);
749
750   return 0;
751 }
752
753 /* Perform a READ BINARY command requesting a maximum of NMAX bytes
754    from OFFSET.  With NMAX = 0 the entire file is read. The result is
755    stored in a newly allocated buffer at the address passed by RESULT.
756    Returns the length of this data at the address of RESULTLEN. */
757 gpg_error_t
758 iso7816_read_binary (int slot, size_t offset, size_t nmax,
759                      unsigned char **result, size_t *resultlen)
760 {
761   int sw;
762   unsigned char *buffer;
763   size_t bufferlen;
764   int read_all = !nmax;
765   size_t n;
766
767   if (!result || !resultlen)
768     return gpg_error (GPG_ERR_INV_VALUE);
769   *result = NULL;
770   *resultlen = 0;
771
772   /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
773      we check for this limit. */
774   if (offset > 32767)
775     return gpg_error (GPG_ERR_INV_VALUE);
776
777   do
778     {
779       buffer = NULL;
780       bufferlen = 0;
781       n = read_all? 0 : nmax;
782       sw = apdu_send_le (slot, 0, 0x00, CMD_READ_BINARY,
783                          ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
784                          n, &buffer, &bufferlen);
785       if ( SW_EXACT_LENGTH_P(sw) )
786         {
787           n = (sw & 0x00ff);
788           sw = apdu_send_le (slot, 0, 0x00, CMD_READ_BINARY,
789                              ((offset>>8) & 0xff), (offset & 0xff) , -1, NULL,
790                              n, &buffer, &bufferlen);
791         }
792
793       if (*result && sw == SW_BAD_P0_P1)
794         {
795           /* Bad Parameter means that the offset is outside of the
796              EF. When reading all data we take this as an indication
797              for EOF.  */
798           break;
799         }
800
801       if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)
802         {
803           /* Make sure that pending buffers are released. */
804           xfree (buffer);
805           xfree (*result);
806           *result = NULL;
807           *resultlen = 0;
808           return map_sw (sw);
809         }
810       if (*result) /* Need to extend the buffer. */
811         {
812           unsigned char *p = xtryrealloc (*result, *resultlen + bufferlen);
813           if (!p)
814             {
815               gpg_error_t err = gpg_error_from_syserror ();
816               xfree (buffer);
817               xfree (*result);
818               *result = NULL;
819               *resultlen = 0;
820               return err;
821             }
822           *result = p;
823           memcpy (*result + *resultlen, buffer, bufferlen);
824           *resultlen += bufferlen;
825           xfree (buffer);
826           buffer = NULL;
827         }
828       else /* Transfer the buffer into our result. */
829         {
830           *result = buffer;
831           *resultlen = bufferlen;
832         }
833       offset += bufferlen;
834       if (offset > 32767)
835         break; /* We simply truncate the result for too large
836                   files. */
837       if (nmax > bufferlen)
838         nmax -= bufferlen;
839       else
840         nmax = 0;
841     }
842   while ((read_all && sw != SW_EOF_REACHED) || (!read_all && nmax));
843
844   return 0;
845 }
846
847 /* Perform a READ RECORD command. RECNO gives the record number to
848    read with 0 indicating the current record.  RECCOUNT must be 1 (not
849    all cards support reading of more than one record).  SHORT_EF
850    should be 0 to read the current EF or contain a short EF. The
851    result is stored in a newly allocated buffer at the address passed
852    by RESULT.  Returns the length of this data at the address of
853    RESULTLEN. */
854 gpg_error_t
855 iso7816_read_record (int slot, int recno, int reccount, int short_ef,
856                      unsigned char **result, size_t *resultlen)
857 {
858   int sw;
859   unsigned char *buffer;
860   size_t bufferlen;
861
862   if (!result || !resultlen)
863     return gpg_error (GPG_ERR_INV_VALUE);
864   *result = NULL;
865   *resultlen = 0;
866
867   /* We can only encode 15 bits in p0,p1 to indicate an offset. Thus
868      we check for this limit. */
869   if (recno < 0 || recno > 255 || reccount != 1
870       || short_ef < 0 || short_ef > 254 )
871     return gpg_error (GPG_ERR_INV_VALUE);
872
873   buffer = NULL;
874   bufferlen = 0;
875   sw = apdu_send_le (slot, 0, 0x00, CMD_READ_RECORD,
876                      recno,
877                      short_ef? short_ef : 0x04,
878                      -1, NULL,
879                      0, &buffer, &bufferlen);
880
881   if (sw != SW_SUCCESS && sw != SW_EOF_REACHED)
882     {
883       /* Make sure that pending buffers are released. */
884       xfree (buffer);
885       xfree (*result);
886       *result = NULL;
887       *resultlen = 0;
888       return map_sw (sw);
889     }
890   *result = buffer;
891   *resultlen = bufferlen;
892
893   return 0;
894 }