Coverage Report

Created: 2025-08-26 06:43

/src/opensc/src/libopensc/apdu.c
Line
Count
Source (jump to first uncovered 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
 */
20
21
#ifdef HAVE_CONFIG_H
22
#include "config.h"
23
#endif
24
25
#include <stdio.h>
26
#include <stdlib.h>
27
#include <assert.h>
28
#include <string.h>
29
30
#include "internal.h"
31
#include "asn1.h"
32
33
/*********************************************************************/
34
/*   low level APDU handling functions                               */
35
/*********************************************************************/
36
37
/** Calculates the length of the encoded APDU in octets.
38
 *  @param  apdu   the APDU
39
 *  @param  proto  the desired protocol
40
 *  @return length of the encoded APDU
41
 */
42
size_t sc_apdu_get_length(const sc_apdu_t *apdu, unsigned int proto)
43
0
{
44
0
  size_t ret = 4;
45
46
0
  switch (apdu->cse) {
47
0
  case SC_APDU_CASE_1:
48
0
    if (proto == SC_PROTO_T0)
49
0
      ret++;
50
0
    break;
51
0
  case SC_APDU_CASE_2_SHORT:
52
0
    ret++;
53
0
    break;
54
0
  case SC_APDU_CASE_2_EXT:
55
0
    ret += (proto == SC_PROTO_T0 ? 1 : 3);
56
0
    break;
57
0
  case SC_APDU_CASE_3_SHORT:
58
0
    ret += 1 + apdu->lc;
59
0
    break;
60
0
  case SC_APDU_CASE_3_EXT:
61
0
    ret += apdu->lc + (proto == SC_PROTO_T0 ? 1 : 3);
62
0
    break;
63
0
  case SC_APDU_CASE_4_SHORT:
64
0
    ret += apdu->lc + (proto != SC_PROTO_T0 ? 2 : 1);
65
0
    break;
66
0
  case SC_APDU_CASE_4_EXT:
67
0
    ret += apdu->lc + (proto == SC_PROTO_T0 ? 1 : 5);
68
0
    break;
69
0
  default:
70
0
    return 0;
71
0
  }
72
0
  return ret;
73
0
}
74
75
/** Encodes a APDU as an octet string
76
 *  @param  ctx     sc_context_t object (used for logging)
77
 *  @param  apdu    APDU to be encoded as an octet string
78
 *  @param  proto   protocol version to be used
79
 *  @param  out     output buffer of size outlen.
80
 *  @param  outlen  size of the output buffer
81
 *  @return SC_SUCCESS on success and an error code otherwise
82
 */
83
int sc_apdu2bytes(sc_context_t *ctx, const sc_apdu_t *apdu,
84
  unsigned int proto, u8 *out, size_t outlen)
85
0
{
86
0
  u8     *p = out;
87
88
0
  size_t len = sc_apdu_get_length(apdu, proto);
89
90
0
  if (out == NULL || outlen < len)
91
0
    return SC_ERROR_INVALID_ARGUMENTS;
92
  /* CLA, INS, P1 and P2 */
93
0
  *p++ = apdu->cla;
94
0
  *p++ = apdu->ins;
95
0
  *p++ = apdu->p1;
96
0
  *p++ = apdu->p2;
97
  /* case depend part */
98
0
  switch (apdu->cse) {
99
0
  case SC_APDU_CASE_1:
100
    /* T0 needs an additional 0x00 byte */
101
0
    if (proto == SC_PROTO_T0)
102
0
      *p = (u8)0x00;
103
0
    break;
104
0
  case SC_APDU_CASE_2_SHORT:
105
0
    *p = (u8)apdu->le;
106
0
    break;
107
0
  case SC_APDU_CASE_2_EXT:
108
0
    if (proto == SC_PROTO_T0)
109
      /* T0 extended APDUs look just like short APDUs */
110
0
      *p = (u8)apdu->le;
111
0
    else {
112
      /* in case of T1 always use 3 bytes for length */
113
0
      *p++ = (u8)0x00;
114
0
      *p++ = (u8)(apdu->le >> 8);
115
0
      *p = (u8)apdu->le;
116
0
    }
117
0
    break;
118
0
  case SC_APDU_CASE_3_SHORT:
119
0
    *p++ = (u8)apdu->lc;
120
0
    memcpy(p, apdu->data, apdu->lc);
121
0
    break;
122
0
  case SC_APDU_CASE_3_EXT:
123
0
    if (proto == SC_PROTO_T0) {
124
      /* in case of T0 the command is transmitted in chunks
125
       * < 255 using the ENVELOPE command ... */
126
0
      if (apdu->lc > 255) {
127
        /* ... so if Lc is greater than 255 bytes
128
         * an error has occurred on a higher level */
129
0
        sc_log(ctx, "invalid Lc length for CASE 3 extended APDU (need ENVELOPE)");
130
0
        return SC_ERROR_INVALID_ARGUMENTS;
131
0
      }
132
0
    }
133
0
    else {
134
      /* in case of T1 always use 3 bytes for length */
135
0
      *p++ = (u8)0x00;
136
0
      *p++ = (u8)(apdu->lc >> 8);
137
0
      *p++ = (u8)apdu->lc;
138
0
    }
139
0
    memcpy(p, apdu->data, apdu->lc);
140
0
    break;
141
0
  case SC_APDU_CASE_4_SHORT:
142
0
    *p++ = (u8)apdu->lc;
143
0
    memcpy(p, apdu->data, apdu->lc);
144
0
    p += apdu->lc;
145
    /* in case of T0 no Le byte is added */
146
0
    if (proto != SC_PROTO_T0)
147
0
      *p = (u8)apdu->le;
148
0
    break;
149
0
  case SC_APDU_CASE_4_EXT:
150
0
    if (proto == SC_PROTO_T0) {
151
      /* again a T0 extended case 4 APDU looks just
152
       * like a short APDU, the additional data is
153
       * transferred using ENVELOPE and GET RESPONSE */
154
0
      *p++ = (u8)apdu->lc;
155
0
      memcpy(p, apdu->data, apdu->lc);
156
0
    }
157
0
    else {
158
0
      *p++ = (u8)0x00;
159
0
      *p++ = (u8)(apdu->lc >> 8);
160
0
      *p++ = (u8)apdu->lc;
161
0
      memcpy(p, apdu->data, apdu->lc);
162
0
      p += apdu->lc;
163
      /* only 2 bytes are use to specify the length of the
164
       * expected data */
165
0
      *p++ = (u8)(apdu->le >> 8);
166
0
      *p = (u8)apdu->le;
167
0
    }
168
0
    break;
169
0
  }
170
171
0
  return SC_SUCCESS;
172
0
}
173
174
int sc_apdu_get_octets(sc_context_t *ctx, const sc_apdu_t *apdu, u8 **buf,
175
  size_t *len, unsigned int proto)
176
0
{
177
0
  size_t  nlen;
178
0
  u8  *nbuf;
179
180
0
  if (apdu == NULL || buf == NULL || len == NULL)
181
0
    return SC_ERROR_INVALID_ARGUMENTS;
182
183
  /* get the estimated length of encoded APDU */
184
0
  nlen = sc_apdu_get_length(apdu, proto);
185
0
  if (nlen == 0)
186
0
    return SC_ERROR_INTERNAL;
187
0
  nbuf = malloc(nlen);
188
0
  if (nbuf == NULL)
189
0
    return SC_ERROR_OUT_OF_MEMORY;
190
  /* encode the APDU in the buffer */
191
0
  if (sc_apdu2bytes(ctx, apdu, proto, nbuf, nlen) != SC_SUCCESS) {
192
0
    free(nbuf);
193
0
    return SC_ERROR_INTERNAL;
194
0
  }
195
0
  *buf = nbuf;
196
0
  *len = nlen;
197
198
0
  return SC_SUCCESS;
199
0
}
200
201
int sc_apdu_set_resp(sc_context_t *ctx, sc_apdu_t *apdu, const u8 *buf,
202
  size_t len)
203
0
{
204
0
  if (len < 2) {
205
    /* no SW1 SW2 ... something went terrible wrong */
206
0
    sc_log(ctx, "invalid response: SW1 SW2 missing");
207
0
    return SC_ERROR_INTERNAL;
208
0
  }
209
  /* set the SW1 and SW2 status bytes (the last two bytes of
210
   * the response */
211
0
  apdu->sw1 = (unsigned int)buf[len - 2];
212
0
  apdu->sw2 = (unsigned int)buf[len - 1];
213
0
  len -= 2;
214
  /* set output length and copy the returned data if necessary */
215
0
  if (len <= apdu->resplen)
216
0
    apdu->resplen = len;
217
218
0
  if (apdu->resplen != 0)
219
0
    memcpy(apdu->resp, buf, apdu->resplen);
220
221
0
  return SC_SUCCESS;
222
0
}
223
224
225
/*********************************************************************/
226
/*   higher level APDU transfer handling functions                   */
227
/*********************************************************************/
228
/*   +------------------+
229
 *   | sc_transmit_apdu |
230
 *   +------------------+
231
 *         |  |  |
232
 *         |  |  |     detect APDU cse               +--------------------+
233
 *         |  |  +---------------------------------> | sc_detect_apdu_cse |
234
 *         |  |                                      +--------------------+
235
 *         |  |        check consistency of APDU     +--------------------+
236
 *         |  +------------------------------------> | sc_check_apdu      |
237
 *         |                                         +--------------------+
238
 *         |           send single APDU              +--------------------+
239
 *         +---------------------------------------> | sc_transmit        |
240
 *                        ^                          +--------------------+
241
 *                        |                               |
242
 *                        |  re-transmit if wrong length  |
243
 *                        |       or GET RESPONSE         |
244
 *                        +-------------------------------+
245
 *                                                        |
246
 *                                                        v
247
 *                                               card->reader->ops->transmit
248
 */
249
250
/** basic consistency check of the sc_apdu_t object
251
 *  @param  ctx   sc_context_t object for error messages
252
 *  @param  apdu  sc_apdu_t object to check
253
 *  @return SC_SUCCESS on success and an error code otherwise
254
 */
255
int
256
sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
257
724
{
258
724
  if ((apdu->cse & ~SC_APDU_SHORT_MASK) == 0) {
259
    /* length check for short APDU */
260
724
    if (apdu->le > 256 || (apdu->lc > 255 && (apdu->flags & SC_APDU_FLAGS_CHAINING) == 0))   {
261
0
      sc_log(card->ctx, "failed length check for short APDU");
262
0
      goto error;
263
0
    }
264
724
  }
265
0
  else if ((apdu->cse & SC_APDU_EXT) != 0) {
266
    /* check if the card supports extended APDUs */
267
0
    if ((card->caps & SC_CARD_CAP_APDU_EXT) == 0) {
268
0
      sc_log(card->ctx, "card doesn't support extended APDUs");
269
0
      goto error;
270
0
    }
271
    /* length check for extended APDU */
272
0
    if (apdu->le > 65536 || apdu->lc > 65535)   {
273
0
      sc_log(card->ctx, "failed length check for extended APDU");
274
0
      goto error;
275
0
    }
276
0
  }
277
0
  else   {
278
0
    goto error;
279
0
  }
280
281
724
  switch (apdu->cse & SC_APDU_SHORT_MASK) {
282
1
  case SC_APDU_CASE_1:
283
    /* no data is sent or received */
284
1
    if (apdu->datalen != 0 || apdu->lc != 0 || apdu->le != 0)
285
0
      goto error;
286
1
    break;
287
38
  case SC_APDU_CASE_2_SHORT:
288
    /* no data is sent */
289
38
    if (apdu->datalen != 0 || apdu->lc != 0)
290
0
      goto error;
291
    /* data is expected       */
292
38
    if (apdu->resplen == 0 || apdu->resp == NULL)
293
0
      goto error;
294
38
    break;
295
87
  case SC_APDU_CASE_3_SHORT:
296
    /* data is sent */
297
87
    if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
298
0
      goto error;
299
    /* no data is expected    */
300
87
    if (apdu->le != 0)
301
0
      goto error;
302
    /* inconsistent datalen   */
303
87
    if (apdu->datalen != apdu->lc)
304
0
      goto error;
305
87
    break;
306
598
  case SC_APDU_CASE_4_SHORT:
307
    /* data is sent */
308
598
    if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
309
0
      goto error;
310
    /* data is expected       */
311
598
    if (apdu->resplen == 0 || apdu->resp == NULL)
312
0
      goto error;
313
    /* inconsistent datalen   */
314
598
    if (apdu->datalen != apdu->lc)
315
0
      goto error;
316
598
    break;
317
598
  default:
318
0
    sc_log(card->ctx, "Invalid APDU case %d", apdu->cse);
319
0
    return SC_ERROR_INVALID_ARGUMENTS;
320
724
  }
321
724
  return SC_SUCCESS;
322
0
error:
323
0
  sc_log(card->ctx, "Invalid Case %d %s APDU:\n"
324
0
    "cse=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%lu le=%lu\n"
325
0
    "resp=%p resplen=%lu data=%p datalen=%lu flags=0x%8.8lx",
326
0
    apdu->cse & SC_APDU_SHORT_MASK,
327
0
    (apdu->cse & SC_APDU_EXT) != 0 ? "extended" : "short",
328
0
    apdu->cse, apdu->cla, apdu->ins, apdu->p1, apdu->p2,
329
0
    (unsigned long) apdu->lc, (unsigned long) apdu->le,
330
0
    apdu->resp, (unsigned long) apdu->resplen,
331
0
    apdu->data, (unsigned long) apdu->datalen, apdu->flags);
332
0
  return SC_ERROR_INVALID_ARGUMENTS;
333
724
}
334
335
/** Tries to determine the APDU type (short or extended) of the supplied
336
 *  APDU if one of the SC_APDU_CASE_? types is used.
337
 *  @param  apdu  APDU object
338
 */
339
static void
340
sc_detect_apdu_cse(const sc_card_t *card, sc_apdu_t *apdu)
341
722
{
342
722
  if (apdu->cse == SC_APDU_CASE_2 || apdu->cse == SC_APDU_CASE_3 ||
343
722
      apdu->cse == SC_APDU_CASE_4) {
344
16
    int btype = apdu->cse & SC_APDU_SHORT_MASK;
345
    /* if either Lc or Le is bigger than the maximum for
346
     * short APDUs and the card supports extended APDUs
347
     * use extended APDUs (unless Lc is greater than
348
     * 255 and command chaining is activated) */
349
16
    if ((apdu->le > 256 || (apdu->lc > 255 && (apdu->flags & SC_APDU_FLAGS_CHAINING) == 0)) &&
350
16
        (card->caps & SC_CARD_CAP_APDU_EXT) != 0)
351
0
      btype |= SC_APDU_EXT;
352
16
    apdu->cse = btype;
353
16
  }
354
722
}
355
356
357
static int
358
sc_single_transmit(struct sc_card *card, struct sc_apdu *apdu)
359
722
{
360
722
  struct sc_context *ctx  = card->ctx;
361
722
  int rv;
362
363
722
  LOG_FUNC_CALLED(ctx);
364
722
  if (card->reader->ops->transmit == NULL)
365
722
    LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "cannot transmit APDU");
366
367
722
  sc_log(ctx,
368
722
         "CLA:%X, INS:%X, P1:%X, P2:%X, data(%"SC_FORMAT_LEN_SIZE_T"u) %p",
369
722
         apdu->cla, apdu->ins, apdu->p1, apdu->p2, apdu->datalen,
370
722
         apdu->data);
371
722
#ifdef ENABLE_SM
372
722
  if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
373
722
        && (apdu->flags & SC_APDU_FLAGS_NO_SM) == 0) {
374
0
    LOG_FUNC_RETURN(ctx, sc_sm_single_transmit(card, apdu));
375
0
  }
376
722
#endif
377
378
  /* send APDU to the reader driver */
379
722
  rv = card->reader->ops->transmit(card->reader, apdu);
380
722
  LOG_TEST_RET(ctx, rv, "unable to transmit APDU");
381
382
722
  LOG_FUNC_RETURN(ctx, rv);
383
722
}
384
385
386
static int
387
sc_set_le_and_transmit(struct sc_card *card, struct sc_apdu *apdu, size_t olen)
388
0
{
389
0
  struct sc_context *ctx  = card->ctx;
390
0
  size_t nlen = apdu->sw2 ? (size_t)apdu->sw2 : 256;
391
0
  int rv;
392
393
0
  LOG_FUNC_CALLED(ctx);
394
  /* we cannot re-transmit the APDU with the demanded Le value
395
   * as the buffer is too small => error */
396
0
  if (olen < nlen)
397
0
    LOG_TEST_RET(ctx, SC_ERROR_WRONG_LENGTH, "wrong length: required length exceeds resplen");
398
399
  /* don't try again if it doesn't work this time */
400
0
  apdu->flags  |= SC_APDU_FLAGS_NO_RETRY_WL;
401
  /* set the new expected length */
402
0
  apdu->resplen = olen;
403
0
  apdu->le      = nlen;
404
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
405
  /* Belpic V1 applets have a problem: if the card sends a 6C XX (only XX bytes available),
406
   * and we resend the command too soon (i.e. the reader is too fast), the card doesn't respond.
407
   * So we build in a delay. */
408
  if (card->type == SC_CARD_TYPE_BELPIC_EID)
409
    msleep(40);
410
#endif
411
412
  /* re-transmit the APDU with new Le length */
413
0
  rv = sc_single_transmit(card, apdu);
414
0
  LOG_TEST_RET(ctx, rv, "cannot re-transmit APDU");
415
416
0
  LOG_FUNC_RETURN(ctx, rv);
417
0
}
418
419
420
static int
421
sc_get_response(struct sc_card *card, struct sc_apdu *apdu, size_t olen)
422
19
{
423
19
  struct sc_context *ctx  = card->ctx;
424
19
  size_t le, minlen, buflen;
425
19
  unsigned char *buf;
426
19
  int rv;
427
428
19
  LOG_FUNC_CALLED(ctx);
429
19
  if (apdu->le == 0) {
430
    /* no data is requested => change return value to 0x9000 and ignore the remaining data */
431
3
    apdu->sw1 = 0x90;
432
3
    apdu->sw2 = 0x00;
433
3
    return SC_SUCCESS;
434
3
  }
435
436
  /* this should _never_ happen */
437
16
  if (!card->ops->get_response)
438
16
    LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "no GET RESPONSE command");
439
440
  /* call GET RESPONSE until we have read all data requested or until the card returns 0x9000,
441
   * whatever happens first. */
442
443
  /* if there are already data in response append a new data to the end of the buffer */
444
16
  buf = apdu->resp + apdu->resplen;
445
446
  /* read as much data as fits in apdu->resp (i.e. min(apdu->resplen, amount of data available)). */
447
16
  buflen = olen - apdu->resplen;
448
449
  /* 0x6100 means at least 256 more bytes to read */
450
16
  le = apdu->sw2 != 0 ? (size_t)apdu->sw2 : 256;
451
  /* we try to read at least as much as bytes as promised in the response bytes */
452
16
  minlen = le;
453
454
17
  do {
455
17
    unsigned char resp[256];
456
17
    size_t resp_len = le;
457
458
    /* we have all the data the caller requested even if the card has more data */
459
17
    if (buflen == 0)
460
7
      break;
461
462
    /* call GET RESPONSE to get more date from the card;
463
     * note: GET RESPONSE returns the left amount of data (== SW2) */
464
10
    memset(resp, 0, sizeof(resp));
465
10
    rv = card->ops->get_response(card, &resp_len, resp);
466
10
    if (rv < 0)   {
467
6
#ifdef ENABLE_SM
468
6
      if (resp_len)   {
469
4
        sc_log_hex(ctx, "SM response data", resp, resp_len);
470
4
        sc_sm_update_apdu_response(card, resp, resp_len, rv, apdu);
471
4
      }
472
6
#endif
473
6
      LOG_TEST_RET(ctx, rv, "GET RESPONSE error");
474
6
    }
475
476
4
    le = resp_len;
477
    /* copy as much as will fit in requested buffer */
478
4
    if (buflen < le)
479
2
      le = buflen;
480
481
4
    memcpy(buf, resp, le);
482
4
    buf    += le;
483
4
    buflen -= le;
484
485
4
    minlen -= le;
486
4
    if (rv != 0)
487
1
      le = minlen = (size_t)rv;
488
3
    else
489
      /* if the card has returned 0x9000 but we still expect data ask for more
490
       * until we have read enough bytes */
491
3
      le = minlen;
492
4
  } while (rv != 0 && minlen != 0);
493
494
  /* we've read all data, let's return 0x9000 */
495
10
  apdu->resplen = buf - apdu->resp;
496
10
  apdu->sw1 = 0x90;
497
10
  apdu->sw2 = 0x00;
498
499
10
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
500
10
}
501
502
503
/** Sends a single APDU to the card reader and calls GET RESPONSE to get the return data if necessary.
504
 *  @param  card  sc_card_t object for the smartcard
505
 *  @param  apdu  APDU to be sent
506
 *  @return SC_SUCCESS on success and an error value otherwise
507
 */
508
static int
509
sc_transmit(sc_card_t *card, sc_apdu_t *apdu)
510
722
{
511
722
  struct sc_context *ctx  = card->ctx;
512
722
  size_t       olen  = apdu->resplen;
513
722
  int          r;
514
515
722
  LOG_FUNC_CALLED(ctx);
516
517
722
  r = sc_single_transmit(card, apdu);
518
722
  LOG_TEST_RET(ctx, r, "transmit APDU failed");
519
520
  /* ok, the APDU was successfully transmitted. Now we have two special cases:
521
   * 1. the card returned 0x6Cxx: in this case APDU will be re-transmitted with Le set to SW2
522
   * (possible only if response buffer size is larger than new Le = SW2)
523
   */
524
722
  if (apdu->sw1 == 0x6C && (apdu->flags & SC_APDU_FLAGS_NO_RETRY_WL) == 0) {
525
0
    r = sc_set_le_and_transmit(card, apdu, olen);
526
0
    LOG_TEST_RET(ctx, r, "cannot re-transmit APDU ");
527
0
  }
528
529
  /* 2. the card returned 0x61xx: more data can be read from the card
530
   *    using the GET RESPONSE command (mostly used in the T0 protocol).
531
   *    Unless the SC_APDU_FLAGS_NO_GET_RESP is set we try to read as
532
   *    much data as possible using GET RESPONSE.
533
   */
534
722
  if (apdu->sw1 == 0x61 && (apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0) {
535
19
    r = sc_get_response(card, apdu, olen);
536
19
    LOG_TEST_RET(ctx, r, "cannot get all data with 'GET RESPONSE'");
537
19
  }
538
539
716
  LOG_FUNC_RETURN(ctx, SC_SUCCESS);
540
716
}
541
542
543
int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
544
722
{
545
722
  int r = SC_SUCCESS;
546
547
722
  if (card == NULL || apdu == NULL)
548
0
    return SC_ERROR_INVALID_ARGUMENTS;
549
550
722
  LOG_FUNC_CALLED(card->ctx);
551
552
  /* determine the APDU type if necessary, i.e. to use
553
   * short or extended APDUs  */
554
722
  sc_detect_apdu_cse(card, apdu);
555
  /* basic APDU consistency check */
556
722
  r = sc_check_apdu(card, apdu);
557
722
  if (r != SC_SUCCESS)
558
0
    return SC_ERROR_INVALID_ARGUMENTS;
559
560
722
  r = sc_lock(card);  /* acquire card lock*/
561
722
  if (r != SC_SUCCESS) {
562
0
    sc_log(card->ctx, "unable to acquire lock");
563
0
    return r;
564
0
  }
565
566
722
#if ENABLE_SM
567
722
  if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
568
722
      && (apdu->flags & SC_APDU_FLAGS_CHAINING) != 0
569
722
      && (apdu->flags & SC_APDU_FLAGS_SM_CHAINING) != 0) {
570
0
    sc_log(card->ctx,"Let SM do the chaining");
571
0
    r = sc_transmit(card, apdu);
572
0
  } else
573
722
#endif
574
722
  if ((apdu->flags & SC_APDU_FLAGS_CHAINING) != 0) {
575
    /* divide et impera: transmit APDU in chunks with Lc <= max_send_size
576
     * bytes using command chaining */
577
2
    size_t    len  = apdu->datalen;
578
2
    const u8  *buf = apdu->data;
579
2
    size_t    max_send_size = sc_get_max_send_size(card);
580
581
4
    while (len != 0) {
582
2
      size_t    plen;
583
2
      sc_apdu_t tapdu;
584
2
      int       last = 0;
585
586
2
      tapdu = *apdu;
587
      /* clear chaining flag */
588
2
      tapdu.flags &= ~SC_APDU_FLAGS_CHAINING;
589
2
      if (len > max_send_size) {
590
        /* adjust APDU case: in case of CASE 4 APDU
591
         * the intermediate APDU are of CASE 3 */
592
0
        if ((tapdu.cse & SC_APDU_SHORT_MASK) == SC_APDU_CASE_4_SHORT)
593
0
          tapdu.cse--;
594
        /* XXX: the chunk size must be adjusted when
595
         *      secure messaging is used */
596
0
        plen          = max_send_size;
597
0
        tapdu.cla    |= 0x10;
598
        /* the intermediate APDU don't expect response data */
599
0
        tapdu.le      = 0;
600
0
        tapdu.resplen = 0;
601
0
        tapdu.resp    = NULL;
602
2
      } else {
603
2
        plen = len;
604
2
        last = 1;
605
2
      }
606
2
      tapdu.data    = buf;
607
2
      tapdu.datalen = tapdu.lc = plen;
608
609
2
      r = sc_check_apdu(card, &tapdu);
610
2
      if (r != SC_SUCCESS) {
611
0
        sc_log(card->ctx, "inconsistent APDU while chaining");
612
0
        break;
613
0
      }
614
615
2
      r = sc_transmit(card, &tapdu);
616
2
      if (r != SC_SUCCESS)
617
0
        break;
618
2
      if (last != 0) {
619
        /* in case of the last APDU set the SW1
620
         * and SW2 bytes in the original APDU */
621
2
        apdu->sw1 = tapdu.sw1;
622
2
        apdu->sw2 = tapdu.sw2;
623
2
        apdu->resplen = tapdu.resplen;
624
2
      } else {
625
        /* otherwise check the status bytes */
626
0
        r = sc_check_sw(card, tapdu.sw1, tapdu.sw2);
627
0
        if (r != SC_SUCCESS)
628
0
          break;
629
0
      }
630
2
      len -= plen;
631
2
      buf += plen;
632
2
    }
633
720
  } else {
634
    /* transmit single APDU */
635
720
    r = sc_transmit(card, apdu);
636
720
  }
637
638
722
  if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
639
    /* give card driver a chance to react on resets */
640
0
    if (card->ops->card_reader_lock_obtained)
641
0
      card->ops->card_reader_lock_obtained(card, 1);
642
0
  }
643
644
  /* all done => release lock */
645
722
  if (sc_unlock(card) != SC_SUCCESS)
646
0
    sc_log(card->ctx, "sc_unlock failed");
647
648
722
  return r;
649
722
}
650
651
652
int
653
sc_bytes2apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
654
0
{
655
0
  const unsigned char *p;
656
0
  size_t len0;
657
658
0
  if (!buf || !apdu)
659
0
    return SC_ERROR_INVALID_ARGUMENTS;
660
661
0
  len0 = len;
662
0
  if (len < 4) {
663
0
    sc_log(ctx, "APDU too short (must be at least 4 bytes)");
664
0
    return SC_ERROR_INVALID_DATA;
665
0
  }
666
667
0
  memset(apdu, 0, sizeof *apdu);
668
0
  p = buf;
669
0
  apdu->cla = *p++;
670
0
  apdu->ins = *p++;
671
0
  apdu->p1 = *p++;
672
0
  apdu->p2 = *p++;
673
0
  len -= 4;
674
675
0
  if (!len) {
676
0
    apdu->cse = SC_APDU_CASE_1;
677
0
    sc_log(ctx,
678
0
           "CASE_1 APDU: %"SC_FORMAT_LEN_SIZE_T"u bytes:\tins=%02x p1=%02x p2=%02x lc=%04"SC_FORMAT_LEN_SIZE_T"x le=%04"SC_FORMAT_LEN_SIZE_T"x",
679
0
           len0, apdu->ins, apdu->p1, apdu->p2, apdu->lc, apdu->le);
680
0
    return SC_SUCCESS;
681
0
  }
682
683
0
  if (*p == 0 && len >= 3) {
684
    /* ...must be an extended APDU */
685
0
    p++;
686
0
    if (len == 3) {
687
0
      apdu->le = (*p++)<<8;
688
0
      apdu->le += *p++;
689
0
      if (apdu->le == 0)
690
0
        apdu->le = 0xffff+1;
691
0
      len -= 3;
692
0
      apdu->cse = SC_APDU_CASE_2_EXT;
693
0
    }
694
0
    else {
695
      /* len > 3 */
696
0
      apdu->lc = (*p++)<<8;
697
0
      apdu->lc += *p++;
698
0
      len -= 3;
699
0
      if (len < apdu->lc) {
700
0
        sc_log(ctx,
701
0
               "APDU too short (need %"SC_FORMAT_LEN_SIZE_T"u more bytes)",
702
0
               apdu->lc - len);
703
0
        return SC_ERROR_INVALID_DATA;
704
0
      }
705
0
      apdu->data = p;
706
0
      apdu->datalen = apdu->lc;
707
0
      len -= apdu->lc;
708
0
      p += apdu->lc;
709
0
      if (!len) {
710
0
        apdu->cse = SC_APDU_CASE_3_EXT;
711
0
      }
712
0
      else {
713
        /* at this point the apdu has a Lc, so Le is on 2 bytes */
714
0
        if (len < 2) {
715
0
          sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "APDU too short (need 2 more bytes)\n");
716
0
          return SC_ERROR_INVALID_DATA;
717
0
        }
718
0
        apdu->le = (*p++)<<8;
719
0
        apdu->le += *p++;
720
0
        if (apdu->le == 0)
721
0
          apdu->le = 0xffff+1;
722
0
        len -= 2;
723
0
        apdu->cse = SC_APDU_CASE_4_EXT;
724
0
      }
725
0
    }
726
0
  }
727
0
  else {
728
    /* ...must be a short APDU */
729
0
    if (len == 1) {
730
0
      apdu->le = *p++;
731
0
      if (apdu->le == 0)
732
0
        apdu->le = 0xff+1;
733
0
      len--;
734
0
      apdu->cse = SC_APDU_CASE_2_SHORT;
735
0
    }
736
0
    else {
737
0
      apdu->lc = *p++;
738
0
      len--;
739
0
      if (len < apdu->lc) {
740
0
        sc_log(ctx,
741
0
               "APDU too short (need %"SC_FORMAT_LEN_SIZE_T"u more bytes)",
742
0
               apdu->lc - len);
743
0
        return SC_ERROR_INVALID_DATA;
744
0
      }
745
0
      apdu->data = p;
746
0
      apdu->datalen = apdu->lc;
747
0
      len -= apdu->lc;
748
0
      p += apdu->lc;
749
0
      if (!len) {
750
0
        apdu->cse = SC_APDU_CASE_3_SHORT;
751
0
      }
752
0
      else {
753
0
        apdu->le = *p++;
754
0
        if (apdu->le == 0)
755
0
          apdu->le = 0xff+1;
756
0
        len--;
757
0
        apdu->cse = SC_APDU_CASE_4_SHORT;
758
0
      }
759
0
    }
760
0
  }
761
0
  if (len) {
762
0
    sc_log(ctx, "APDU too long (%lu bytes extra)",(unsigned long) len);
763
0
    return SC_ERROR_INVALID_DATA;
764
0
  }
765
766
0
  sc_log(ctx,
767
0
         "Case %d %s APDU, %"SC_FORMAT_LEN_SIZE_T"u bytes:\tins=%02x p1=%02x p2=%02x lc=%04"SC_FORMAT_LEN_SIZE_T"x le=%04"SC_FORMAT_LEN_SIZE_T"x",
768
0
         apdu->cse & SC_APDU_SHORT_MASK,
769
0
         (apdu->cse & SC_APDU_EXT) != 0 ? "extended" : "short",
770
0
         len0, apdu->ins, apdu->p1, apdu->p2, apdu->lc,
771
0
         apdu->le);
772
773
0
  return SC_SUCCESS;
774
0
}