Coverage Report

Created: 2026-03-01 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/ef-gdo.c
Line
Count
Source
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
1.91k
{
34
1.91k
  int r = SC_SUCCESS, iccsn_found = 0, chn_found = 0;
35
1.91k
  const unsigned char *p = gdo;
36
1.91k
  size_t left = gdo_len;
37
38
5.70k
  while (left >= 2) {
39
4.04k
    unsigned int cla, tag;
40
4.04k
    size_t tag_len;
41
42
4.04k
    r = sc_asn1_read_tag(&p, left, &cla, &tag, &tag_len);
43
4.04k
    if (r != SC_SUCCESS) {
44
138
      if (r == SC_ERROR_ASN1_END_OF_CONTENTS) {
45
        /* not enough data */
46
84
        r = SC_SUCCESS;
47
84
      }
48
138
      break;
49
138
    }
50
3.90k
    if (p == NULL) {
51
      /* done parsing */
52
119
      break;
53
119
    }
54
55
3.78k
    if (cla == SC_ASN1_TAG_APPLICATION) {
56
2.15k
      switch (tag) {
57
1.13k
        case 0x1A:
58
1.13k
          iccsn_found = 1;
59
1.13k
          if (iccsn && iccsn_len) {
60
1.13k
            memcpy(iccsn, p, MIN(tag_len, *iccsn_len));
61
1.13k
            *iccsn_len = MIN(tag_len, *iccsn_len);
62
1.13k
          }
63
1.13k
          break;
64
213
        case 0x1F20:
65
213
          chn_found = 1;
66
213
          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
213
          break;
71
2.15k
      }
72
2.15k
    }
73
74
3.78k
    p += tag_len;
75
3.78k
    left = gdo_len - (p - gdo);
76
3.78k
  }
77
78
1.91k
  if (!iccsn_found && iccsn_len)
79
1.75k
    *iccsn_len = 0;
80
1.91k
  if (!chn_found && chn_len)
81
0
    *chn_len = 0;
82
83
1.91k
  return r;
84
1.91k
}
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
4.84k
{
93
4.84k
  struct sc_context *ctx;
94
4.84k
  struct sc_path path;
95
4.84k
  struct sc_file *file;
96
4.84k
  unsigned char *gdo = NULL;
97
4.84k
  size_t gdo_len = 0;
98
4.84k
  int r;
99
100
4.84k
  if (!card)
101
0
    return SC_ERROR_INVALID_ARGUMENTS;
102
103
4.84k
  ctx = card->ctx;
104
105
4.84k
  LOG_FUNC_CALLED(ctx);
106
107
4.84k
  sc_format_path("3F002F02", &path);
108
4.84k
  r = sc_select_file(card, &path, &file);
109
4.84k
  LOG_TEST_GOTO_ERR(ctx, r, "Cannot select EF(GDO) file");
110
111
1.99k
  if (file->size) {
112
123
    gdo_len = file->size;
113
1.87k
  } else {
114
1.87k
    gdo_len = 64;
115
1.87k
  }
116
1.99k
  gdo = malloc(gdo_len);
117
1.99k
  if (!gdo) {
118
0
    r = SC_ERROR_OUT_OF_MEMORY;
119
0
    goto err;
120
0
  }
121
122
1.99k
  r = sc_read_binary(card, 0, gdo, gdo_len, 0);
123
1.99k
  LOG_TEST_GOTO_ERR(ctx, r, "Cannot read EF(GDO) file");
124
125
1.91k
  r = sc_parse_ef_gdo_content(gdo, r, iccsn, iccsn_len, chn, chn_len);
126
127
4.84k
err:
128
4.84k
  sc_file_free(file);
129
4.84k
  free(gdo);
130
131
4.84k
  LOG_FUNC_RETURN(ctx, r);
132
4.84k
}