root/trunk/src/libopensc/apdu.c

Revision 3260, 17.7 kB (checked in by aj, 15 months ago)

fix typo, found by Gürer Özen.

Line 
1/*
2 * apdu.c: basic APDU handling functions
3 *
4 * Copyright (C) 2005 Nils Larsch <nils@larsch.net>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library 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 GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <assert.h>
24#include <string.h>
25
26#include "internal.h"
27
28/*********************************************************************/
29/*   low level APDU handling functions                               */
30/*********************************************************************/
31
32/** Calculates the length of the encoded APDU in octets.
33 *  @param  apdu   the APDU
34 *  @param  proto  the desired protocol
35 *  @return length of the encoded APDU
36 */
37static size_t sc_apdu_get_length(const sc_apdu_t *apdu, unsigned int proto)
38{
39        size_t ret = 4;
40
41        switch (apdu->cse) {
42        case SC_APDU_CASE_1:
43                if (proto == SC_PROTO_T0)
44                        ret++;
45                break;
46        case SC_APDU_CASE_2_SHORT:
47                ret++;
48                break;
49        case SC_APDU_CASE_2_EXT:
50                ret += (proto == SC_PROTO_T0 ? 1 : 3);
51                break;
52        case SC_APDU_CASE_3_SHORT:
53                ret += 1 + apdu->lc;
54                break;
55        case SC_APDU_CASE_3_EXT:
56                ret += apdu->lc + (proto == SC_PROTO_T0 ? 1 : 3);
57                break;
58        case SC_APDU_CASE_4_SHORT:
59                ret += apdu->lc + (proto != SC_PROTO_T0 ? 2 : 1);
60                break;
61        case SC_APDU_CASE_4_EXT:
62                ret += apdu->lc + (proto == SC_PROTO_T0 ? 1 : 5);
63                break;
64        default:
65                return 0;
66        }
67        return ret;
68}
69
70/** Encodes a APDU as an octet string
71 *  @param  ctx     sc_context_t object (used for logging)
72 *  @param  apdu    APDU to be encoded as an octet string
73 *  @param  proto   protocol version to be used
74 *  @param  out     output buffer of size outlen.
75 *  @param  outlen  size of hte output buffer
76 *  @return SC_SUCCESS on success and an error code otherwise
77 */
78static int sc_apdu2bytes(sc_context_t *ctx, const sc_apdu_t *apdu,
79        unsigned int proto, u8 *out, size_t outlen)
80{
81        u8     *p = out;
82
83        size_t len = sc_apdu_get_length(apdu, proto);
84
85        if (out == NULL || outlen < len)
86                return SC_ERROR_INVALID_ARGUMENTS;
87        /* CLA, INS, P1 and P2 */
88        *p++ = apdu->cla;
89        *p++ = apdu->ins;
90        *p++ = apdu->p1;
91        *p++ = apdu->p2;
92        /* case depend part */
93        switch (apdu->cse) {
94        case SC_APDU_CASE_1:
95                /* T0 needs an additional 0x00 byte */
96                if (proto == SC_PROTO_T0)
97                        *p++ = (u8)0x00;
98                break;
99        case SC_APDU_CASE_2_SHORT:
100                *p++ = (u8)apdu->le;
101                break;
102        case SC_APDU_CASE_2_EXT:
103                if (proto == SC_PROTO_T0)
104                        /* T0 extended APDUs look just like short APDUs */
105                        *p++ = (u8)apdu->le;
106                else {
107                        /* in case of T1 always use 3 bytes for length */
108                        *p++ = (u8)0x00;
109                        *p++ = (u8)(apdu->le >> 8);
110                        *p++ = (u8)apdu->le;
111                }
112                break;
113        case SC_APDU_CASE_3_SHORT:
114                *p++ = (u8)apdu->lc;
115                memcpy(p, apdu->data, apdu->lc);
116                p += apdu->lc;
117                break;
118        case SC_APDU_CASE_3_EXT:
119                if (proto == SC_PROTO_T0) {
120                        /* in case of T0 the command is transmitted in chunks
121                         * < 255 using the ENVELOPE command ... */
122                        if (apdu->lc > 255) {
123                                /* ... so if Lc is greater than 255 bytes
124                                 * an error has occurred on a higher level */
125                                sc_error(ctx, "invalid Lc length for CASE 3 "
126                                        "extended APDU (need ENVELOPE)");
127                                return SC_ERROR_INVALID_ARGUMENTS;
128                        }
129                } else {
130                        /* in case of T1 always use 3 bytes for length */
131                        *p++ = (u8)0x00;
132                        *p++ = (u8)(apdu->lc >> 8);
133                        *p++ = (u8)apdu->lc;
134                }
135                memcpy(p, apdu->data, apdu->lc);
136                p += apdu->lc;
137                break;
138        case SC_APDU_CASE_4_SHORT:
139                *p++ = (u8)apdu->lc;
140                memcpy(p, apdu->data, apdu->lc);
141                p += apdu->lc;
142                /* in case of T0 no Le byte is added */
143                if (proto != SC_PROTO_T0)
144                        *p++ = (u8)apdu->le;
145                break;
146        case SC_APDU_CASE_4_EXT:
147                if (proto == SC_PROTO_T0) {
148                        /* again a T0 extended case 4 APDU looks just
149                         * like a short APDU, the additional data is
150                         * transferred using ENVELOPE and GET RESPONSE */
151                        *p++ = (u8)apdu->lc;
152                        memcpy(p, apdu->data, apdu->lc);
153                        p += apdu->lc & 0xff;
154                } else {
155                        *p++ = (u8)0x00;
156                        *p++ = (u8)(apdu->lc >> 8);
157                        *p++ = (u8)apdu->lc;
158                        memcpy(p, apdu->data, apdu->lc);
159                        p += apdu->lc;
160                        /* only 2 bytes are use to specify the length of the
161                         * expected data */
162                        *p++ = (u8)(apdu->le >> 8);
163                        *p++ = (u8)apdu->le;
164                }
165                break;
166        }
167
168        return SC_SUCCESS;
169}
170
171void sc_apdu_log(sc_context_t *ctx, const u8 *data, size_t len, int is_out)
172{
173        size_t blen = len * 5 + 128;
174        char   *buf = malloc(blen);
175        if (buf == NULL)
176                return;
177
178        sc_hex_dump(ctx, data, len, buf, blen);
179
180        sc_debug(ctx, "\n%s APDU data [%5u bytes] =====================================\n"
181                "%s"
182                "======================================================================\n",
183                is_out != 0 ? "Outgoing" : "Incoming", len,
184                buf);
185        free(buf);
186}
187
188int sc_apdu_get_octets(sc_context_t *ctx, const sc_apdu_t *apdu, u8 **buf,
189        size_t *len, unsigned int proto)
190{
191        size_t  nlen;
192        u8      *nbuf;
193
194        if (apdu == NULL || buf == NULL || len == NULL)
195                return SC_ERROR_INVALID_ARGUMENTS;
196
197        /* get the estimated length of encoded APDU */
198        nlen = sc_apdu_get_length(apdu, proto);
199        if (nlen == 0)
200                return SC_ERROR_INTERNAL;
201        nbuf = malloc(nlen);
202        if (nbuf == NULL)
203                return SC_ERROR_MEMORY_FAILURE;
204        /* encode the APDU in the buffer */
205        if (sc_apdu2bytes(ctx, apdu, proto, nbuf, nlen) != SC_SUCCESS)
206                return SC_ERROR_INTERNAL;
207        *buf = nbuf;
208        *len = nlen;
209
210        return SC_SUCCESS;
211}
212
213int sc_apdu_set_resp(sc_context_t *ctx, sc_apdu_t *apdu, const u8 *buf,
214        size_t len)
215{
216        if (len < 2) {
217                /* no SW1 SW2 ... something went terrible wrong */
218                sc_error(ctx, "invalid response: SW1 SW2 missing");
219                return SC_ERROR_INTERNAL;
220        }
221        /* set the SW1 and SW2 status bytes (the last two bytes of
222         * the response */
223        apdu->sw1 = (unsigned int)buf[len - 2];
224        apdu->sw2 = (unsigned int)buf[len - 1];
225        len -= 2;
226        /* set output length and copy the returned data if necessary */
227        if (len <= apdu->resplen)
228                apdu->resplen = len;
229
230        if (apdu->resplen != 0)
231                memcpy(apdu->resp, buf, apdu->resplen);
232
233        return SC_SUCCESS;
234}
235
236/*********************************************************************/
237/*   higher level APDU transfer handling functions                   */
238/*********************************************************************/
239/*   +------------------+
240 *   | sc_transmit_apdu |
241 *   +------------------+
242 *         |  |  |
243 *         |  |  |     detect APDU cse               +--------------------+
244 *         |  |  +---------------------------------> | sc_detect_apdu_cse |
245 *         |  |                                      +--------------------+
246 *         |  |        check consistency of APDU     +--------------------+
247 *         |  +------------------------------------> | sc_check_apdu      |
248 *         |                                         +--------------------+
249 *         |           send single APDU              +--------------------+
250 *         +---------------------------------------> | do_single_transmit |
251 *                        ^                          +--------------------+
252 *                        |                               |
253 *                        |  re-transmit if wrong length  |
254 *                        |       or GET RESPONSE         |
255 *                        +-------------------------------+
256 *                                                        |
257 *                                                        v
258 *                                               card->reader->ops->tranmit
259 */
260
261/** basic consistency check of the sc_apdu_t object
262 *  @param  ctx   sc_context_t object for error messages
263 *  @param  apdu  sc_apdu_t object to check
264 *  @return SC_SUCCESS on success and an error code otherwise
265 */
266static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
267{
268        if ((apdu->cse & ~SC_APDU_SHORT_MASK) == 0) {
269                /* length check for short APDU    */
270                if (apdu->le > 256 || (apdu->lc > 255 &&
271                    (apdu->flags & SC_APDU_FLAGS_CHAINING) == 0))
272                        goto error;
273        } else if ((apdu->cse & SC_APDU_EXT) != 0) {
274                /* check if the card support extended APDUs */
275                if ((card->caps & SC_CARD_CAP_APDU_EXT) == 0) {
276                        sc_error(card->ctx, "card doesn't support extended APDUs");
277                        goto error;
278                }
279                /* length check for extended APDU */
280                if (apdu->le > 65536 || apdu->lc > 65535)
281                        goto error;
282        } else
283                goto error;
284
285        switch (apdu->cse & SC_APDU_SHORT_MASK) {
286        case SC_APDU_CASE_1:
287                /* no data is send or received */
288                if (apdu->datalen != 0 || apdu->lc != 0 || apdu->le != 0)
289                        goto error;
290                break;
291        case SC_APDU_CASE_2_SHORT:
292                /* no data is send        */
293                if (apdu->datalen != 0 || apdu->lc != 0)
294                        goto error;
295                /* data is expected       */
296                if (apdu->le == 0 || apdu->resplen == 0 || apdu->resp == NULL)
297                        goto error;
298                /* return buffer to small */
299                if (apdu->resplen < apdu->le)
300                        goto error;
301                break;
302        case SC_APDU_CASE_3_SHORT:
303                /* data is send           */
304                if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
305                        goto error;
306                /* no data is expected    */
307                if (apdu->le != 0)
308                        goto error;
309                /* inconsistent datalen   */
310                if (apdu->datalen != apdu->lc)
311                        goto error;
312                break;
313        case SC_APDU_CASE_4_SHORT:
314                /* data is send           */
315                if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
316                        goto error;
317                /* data is expected       */
318                if (apdu->le == 0 || apdu->resplen == 0 || apdu->resp == NULL)
319                        goto error;
320                /* return buffer to small */
321                if (apdu->resplen < apdu->le)
322                        goto error;
323                /* inconsistent datalen   */
324                if (apdu->datalen != apdu->lc)
325                        goto error;
326                break;
327        default:
328                sc_error(card->ctx, "Invalid APDU case %d\n", apdu->cse);
329                return SC_ERROR_INVALID_ARGUMENTS;
330        }
331        return SC_SUCCESS;
332error:
333        sc_error(card->ctx, "Invalid Case %d %s APDU:\n"
334                "cse=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%lu le=%lu\n"
335                "resp=%p resplen=%lu data=%p datalen=%lu",
336                apdu->cse & SC_APDU_SHORT_MASK,
337                (apdu->cse & SC_APDU_EXT) != 0 ? "extended" : "short",
338                apdu->cse, apdu->cla, apdu->ins, apdu->p1, apdu->p2,
339                (unsigned long) apdu->lc, (unsigned long) apdu->le,
340                apdu->resp, (unsigned long) apdu->resplen,
341                apdu->data, (unsigned long) apdu->datalen);
342        return SC_ERROR_INVALID_ARGUMENTS;
343}
344
345/** Tries to determine the APDU type (short or extended) of the supplied
346 *  APDU if one of the SC_APDU_CASE_? types is used.
347 *  @param  apdu  APDU object
348 */
349static void sc_detect_apdu_cse(const sc_card_t *card, sc_apdu_t *apdu)
350{
351        if (apdu->cse == SC_APDU_CASE_2 || apdu->cse == SC_APDU_CASE_3 ||
352            apdu->cse == SC_APDU_CASE_4) {
353                int btype = apdu->cse & SC_APDU_SHORT_MASK;
354                /* if either Lc or Le is bigger than the maximun for
355                 * short APDUs and the card supports extended APDUs
356                 * use extended APDUs (unless Lc is greater than
357                 * 255 and command chaining is activated) */
358                if ((apdu->le > 256 || (apdu->lc > 255 && (apdu->flags & SC_APDU_FLAGS_CHAINING) == 0)) &&
359                    (card->caps & SC_CARD_CAP_APDU_EXT) != 0)
360                        btype |= SC_APDU_EXT;
361                apdu->cse = btype;
362        }
363}
364
365
366/** Sends a single APDU to the card reader and calls
367 *  GET RESPONSE to get the return data if necessary.
368 *  @param  card  sc_card_t object for the smartcard
369 *  @param  apdu  APDU to be send
370 *  @return SC_SUCCESS on success and an error value otherwise
371 */
372static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu)
373{
374        int          r;
375        size_t       olen  = apdu->resplen;
376        sc_context_t *ctx  = card->ctx;
377
378        /* XXX: insert secure messaging here (?), i.e. something like
379        if (card->sm_ctx->use_sm != 0) {
380                r = card->ops->sm_transform(...);
381                if (r != SC_SUCCESS)
382                        ...
383                r = sc_check_apdu(...);
384                if (r != SC_SUCCESS)
385                        ...
386        }
387        */
388
389        /* send APDU to the reader driver */
390        if (card->reader->ops->transmit == NULL)
391                return SC_ERROR_NOT_SUPPORTED;
392        r = card->reader->ops->transmit(card->reader, card->slot, apdu);
393        if (r != 0) {
394                sc_error(ctx, "unable to transmit APDU");
395                return r;
396        }
397        /* ok, the APDU was successfully transmitted. Now we have two
398         * special cases:
399         * 1. the card returned 0x6Cxx: in this case we re-trasmit the APDU
400         *    wit hLe set to SW2 (this is course only possible if the
401         *    response buffer size is larger than the new Le = SW2)
402         */
403        if (apdu->sw1 == 0x6C && (apdu->flags & SC_APDU_FLAGS_NO_RETRY_WL) == 0) {
404                size_t nlen = apdu->sw2 != 0 ? (size_t)apdu->sw2 : 256;
405                if (olen >= nlen) {
406                        /* don't try again if it doesn't work this time */
407                        apdu->flags  |= SC_APDU_FLAGS_NO_GET_RESP;
408                        /* set the new expected length */
409                        apdu->resplen = olen;
410                        apdu->le      = nlen;
411                        /* as some reader/smartcards can't handle an immediate
412                         * re-transmit so we optionally need to sleep for
413                         * a while */
414                        if (card->wait_resend_apdu != 0)
415                                msleep(card->wait_resend_apdu);
416                        /* re-transmit the APDU with new Le length */
417                        r = card->reader->ops->transmit(card->reader, card->slot, apdu);
418                        if (r != SC_SUCCESS) {
419                                sc_error(ctx, "unable to transmit APDU");
420                                return r;
421                        }
422                } else {
423                        /* we cannot re-transmit the APDU with the demanded
424                         * Le value as the buffer is too small => error */
425                        sc_debug(ctx, "wrong length: required length exceeds resplen");
426                        return SC_ERROR_WRONG_LENGTH;
427                }
428        }
429
430        /* 2. the card returned 0x61xx: more data can be read from the card
431         *    using the GET RESPONSE command (mostly used in the T0 protocol).
432         *    Unless the SC_APDU_FLAGS_NO_GET_RESP is set we try to read as
433         *    much data as possible using GET RESPONSE.
434         */
435        if (apdu->sw1 == 0x61 && (apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0) {
436                if (apdu->le == 0) {
437                        /* no data is requested => change return value to
438                         * 0x9000 and ignore the remaining data */
439                        /* FIXME: why not return 0x61xx ? It's not an
440                         *        error */
441                        apdu->sw1 = 0x90;
442                        apdu->sw2 = 0x00;
443                       
444                } else {
445                        /* call GET RESPONSE until we have read all data
446                         * requested or until the card retuns 0x9000,
447                         * whatever happens first.
448                         */
449                        size_t le, minlen, buflen;
450                        u8     *buf;
451
452                        if (card->ops->get_response == NULL) {
453                                /* this should _never_ happen */
454                                sc_error(ctx, "no GET RESPONSE command\n");
455                                return SC_ERROR_NOT_SUPPORTED;
456                        }
457
458                        /* if the command already returned some data
459                         * append the new data to the end of the buffer
460                         */
461                        buf = apdu->resp + apdu->resplen;
462
463                        /* read as much data as fits in apdu->resp (i.e.
464                         * max(apdu->resplen, amount of data available)).
465                         */
466                        buflen = olen - apdu->resplen;
467
468                        /* 0x6100 means at least 256 more bytes to read */
469                        le = apdu->sw2 != 0 ? (size_t)apdu->sw2 : 256;
470                        /* we try to read at least as much as bytes as
471                         * promised in the response bytes */
472                        minlen = le;
473
474                        do {
475                                u8 tbuf[256];
476                                /* call GET RESPONSE to get more date from
477                                 * the card; note: GET RESPONSE returns the
478                                 * amount of data left (== SW2) */
479                                r = card->ops->get_response(card, &le, tbuf);
480                                if (r < 0)
481                                        SC_FUNC_RETURN(ctx, 2, r);
482
483                                if (buflen < le)
484                                        return SC_ERROR_WRONG_LENGTH;
485
486                                memcpy(buf, tbuf, le);
487                                buf    += le;
488                                buflen -= le;
489
490                                minlen -= le;
491                                if (r != 0)
492                                        le = minlen = (size_t)r;
493                                else
494                                        /* if the card has returned 0x9000 but
495                                         * we still expect data ask for more
496                                         * until we have read enough bytes */
497                                        le = minlen;
498                        } while (r != 0 || minlen != 0);
499                        /* we've read all data, let's return 0x9000 */
500                        apdu->resplen = buf - apdu->resp;
501                        apdu->sw1 = 0x90;
502                        apdu->sw2 = 0x00;
503                }
504        }
505
506        return SC_SUCCESS;
507}
508
509int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
510{
511        int r = SC_SUCCESS;
512
513        if (card == NULL || apdu == NULL)
514                return SC_ERROR_INVALID_ARGUMENTS;
515
516        SC_FUNC_CALLED(card->ctx, 4);
517
518        /* determine the APDU type if necessary, i.e. to use
519         * short or extended APDUs  */
520        sc_detect_apdu_cse(card, apdu);
521        /* basic APDU consistency check */
522        r = sc_check_apdu(card, apdu);
523        if (r != SC_SUCCESS)
524                return SC_ERROR_INVALID_ARGUMENTS;
525
526        r = sc_lock(card);      /* acquire card lock*/
527        if (r != SC_SUCCESS) {
528                sc_error(card->ctx, "unable to acquire lock");
529                return r;
530        }
531
532        if ((apdu->flags & SC_APDU_FLAGS_CHAINING) != 0) {
533                /* divide et impera: transmit APDU in chunks with Lc < 255
534                 * bytes using command chaining */
535                size_t    len  = apdu->datalen;
536                const u8  *buf = apdu->data;
537
538                while (len != 0) {
539                        size_t    plen;
540                        sc_apdu_t tapdu;
541                        int       last = 0;
542
543                        tapdu = *apdu;
544                        /* clear chaining flag */
545                        tapdu.flags &= ~SC_APDU_FLAGS_CHAINING;
546                        if (len > 255) {
547                                /* adjust APDU case: in case of CASE 4 APDU
548                                 * the intermediate APDU are of CASE 3 */
549                                if ((tapdu.cse & SC_APDU_SHORT_MASK) == SC_APDU_CASE_4_SHORT)
550                                        tapdu.cse--;
551                                /* XXX: the chunk size must be adjusted when
552                                 *      secure messaging is used */
553                                plen          = 255;
554                                tapdu.cla    |= 0x10;
555                                tapdu.le      = 0;
556                                /* the intermediate APDU don't expect data */
557                                tapdu.lc      = 0;
558                                tapdu.resplen = 0;
559                                tapdu.resp    = NULL;
560                        } else {
561                                plen = len;
562                                last = 1;
563                        }
564                        tapdu.data    = buf;
565                        tapdu.datalen = tapdu.lc = plen;
566
567                        r = sc_check_apdu(card, &tapdu);
568                        if (r != SC_SUCCESS) {
569                                sc_error(card->ctx, "inconsistent APDU while chaining");
570                                break;
571                        }
572
573                        r = do_single_transmit(card, &tapdu);
574                        if (r != SC_SUCCESS)
575                                break;
576                        if (last != 0) {
577                                /* in case of the last APDU set the SW1
578                                 * and SW2 bytes in the original APDU */
579                                apdu->sw1 = tapdu.sw1;
580                                apdu->sw2 = tapdu.sw2;
581                                apdu->resplen = tapdu.resplen;
582                        } else {
583                                /* otherwise check the status bytes */
584                                r = sc_check_sw(card, tapdu.sw1, tapdu.sw2);
585                                if (r != SC_SUCCESS)
586                                        break;
587                        }
588                        len -= plen;
589                        buf += plen;
590                }
591        } else 
592                /* transmit single APDU */
593                r = do_single_transmit(card, apdu);
594        /* all done => release lock */
595        if (sc_unlock(card) != SC_SUCCESS)
596                sc_error(card->ctx, "sc_unlock failed");
597
598        return r;
599}
Note: See TracBrowser for help on using the browser.