Coverage Report

Created: 2026-02-26 06:59

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