Coverage Report

Created: 2025-07-11 06:59

/src/opensc/src/libopensc/ef-gdo.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * ef-atr.c: Stuff for handling EF(GDO)
3
 *
4
 * Copyright (C) 2017  Frank Morgner <frankmorgner@gmail.com>
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
#ifdef HAVE_CONFIG_H
21
#include "config.h"
22
#endif
23
24
#include "asn1.h"
25
#include "internal.h"
26
#include <stdlib.h>
27
#include <string.h>
28
29
static int
30
sc_parse_ef_gdo_content(const unsigned char *gdo, size_t gdo_len,
31
    unsigned char *iccsn, size_t *iccsn_len,
32
    unsigned char *chn, size_t *chn_len)
33
61
{
34
61
  int r = SC_SUCCESS, iccsn_found = 0, chn_found = 0;
35
61
  const unsigned char *p = gdo;
36
61
  size_t left = gdo_len;
37
38
471
  while (left >= 2) {
39
446
    unsigned int cla, tag;
40
446
    size_t tag_len;
41
42
446
    r = sc_asn1_read_tag(&p, left, &cla, &tag, &tag_len);
43
446
    if (r != SC_SUCCESS) {
44
17
      if (r == SC_ERROR_ASN1_END_OF_CONTENTS) {
45
        /* not enough data */
46
15
        r = SC_SUCCESS;
47
15
      }
48
17
      break;
49
17
    }
50
429
    if (p == NULL) {
51
      /* done parsing */
52
19
      break;
53
19
    }
54
55
410
    if (cla == SC_ASN1_TAG_APPLICATION) {
56
324
      switch (tag) {
57
67
        case 0x1A:
58
67
          iccsn_found = 1;
59
67
          if (iccsn && iccsn_len) {
60
67
            memcpy(iccsn, p, MIN(tag_len, *iccsn_len));
61
67
            *iccsn_len = MIN(tag_len, *iccsn_len);
62
67
          }
63
67
          break;
64
1
        case 0x1F20:
65
1
          chn_found = 1;
66
1
          if (chn && chn_len) {
67
0
            memcpy(chn, p, MIN(tag_len, *chn_len));
68
0
            *chn_len = MIN(tag_len, *chn_len);
69
0
          }
70
1
          break;
71
324
      }
72
324
    }
73
74
410
    p += tag_len;
75
410
    left = gdo_len - (p - gdo);
76
410
  }
77
78
61
  if (!iccsn_found && iccsn_len)
79
45
    *iccsn_len = 0;
80
61
  if (!chn_found && chn_len)
81
0
    *chn_len = 0;
82
83
61
  return r;
84
61
}
85
86
87
88
int
89
sc_parse_ef_gdo(struct sc_card *card,
90
    unsigned char *iccsn, size_t *iccsn_len,
91
    unsigned char *chn, size_t *chn_len)
92
403
{
93
403
  struct sc_context *ctx;
94
403
  struct sc_path path;
95
403
  struct sc_file *file;
96
403
  unsigned char *gdo = NULL;
97
403
  size_t gdo_len = 0;
98
403
  int r;
99
100
403
  if (!card)
101
0
    return SC_ERROR_INVALID_ARGUMENTS;
102
103
403
  ctx = card->ctx;
104
105
403
  LOG_FUNC_CALLED(ctx);
106
107
403
  sc_format_path("3F002F02", &path);
108
403
  r = sc_select_file(card, &path, &file);
109
403
  LOG_TEST_GOTO_ERR(ctx, r, "Cannot select EF(GDO) file");
110
111
69
  if (file->size) {
112
11
    gdo_len = file->size;
113
58
  } else {
114
58
    gdo_len = 64;
115
58
  }
116
69
  gdo = malloc(gdo_len);
117
69
  if (!gdo) {
118
0
    r = SC_ERROR_OUT_OF_MEMORY;
119
0
    goto err;
120
0
  }
121
122
69
  r = sc_read_binary(card, 0, gdo, gdo_len, 0);
123
69
  LOG_TEST_GOTO_ERR(ctx, r, "Cannot read EF(GDO) file");
124
125
61
  r = sc_parse_ef_gdo_content(gdo, r, iccsn, iccsn_len, chn, chn_len);
126
127
403
err:
128
403
  sc_file_free(file);
129
403
  free(gdo);
130
131
403
  LOG_FUNC_RETURN(ctx, r);
132
403
}