Coverage Report

Created: 2025-08-24 06:59

/src/opensc/src/libopensc/pkcs15-atrust-acos.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * partial PKCS15 emulation for A-Trust ACOS cards
3
 *
4
 * Copyright (C) 2005  Franz Brandl <brandl@a-trust.at> based on work from
5
 *                     Nils Larsch  <larsch@trustcenter.de>, TrustCenter AG
6
 *
7
 * This library is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with this library; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
 */
21
22
#ifdef HAVE_CONFIG_H
23
#include "config.h"
24
#endif
25
26
#include <stdlib.h>
27
#include <string.h>
28
#include <stdio.h>
29
30
#include "internal.h"
31
#include "common/compat_strlcpy.h"
32
#include "libopensc/pkcs15.h"
33
#include "libopensc/cardctl.h"
34
35
0
#define MANU_ID   "A-Trust"
36
0
#define CARD_LABEL  "a.sign Premium a"
37
38
typedef struct cdata_st {
39
  const char *label;
40
  int     authority;
41
  const char *path;
42
  const char *id;
43
  int         obj_flags;
44
} cdata;
45
46
typedef struct pdata_st {
47
  const char *id;
48
  const char *label;
49
  const char *path;
50
  int         ref;
51
  int         type;
52
  unsigned int maxlen;
53
  unsigned int minlen;
54
  unsigned int storedlen;
55
  int         flags;
56
  int         tries_left;
57
  const char  pad_char;
58
  int         obj_flags;
59
} pindata;
60
61
typedef struct prdata_st {
62
  const char *id;
63
  const char *label;
64
  unsigned int modulus_len;
65
  int         usage;
66
  const char *path;
67
  int         ref;
68
  const char *auth_id;
69
  int         obj_flags;
70
} prdata;
71
72
static int get_cert_len(sc_card_t *card, sc_path_t *path)
73
0
{
74
0
  int r;
75
0
  u8  buf[8];
76
77
0
  r = sc_select_file(card, path, NULL);
78
0
  if (r < 0)
79
0
    return 0;
80
0
  r = sc_read_binary(card, 0, buf, sizeof(buf), 0);
81
0
  if (r < 0)
82
0
    return 0;
83
0
  if (buf[0] != 0x30 || buf[1] != 0x82)
84
0
    return 0;
85
0
  path->index = 0;
86
0
  path->count = ((((int) buf[2]) << 8) | buf[3]) + 4;
87
0
  return 1;
88
0
}
89
90
static int acos_detect_card(sc_pkcs15_card_t *p15card)
91
0
{
92
0
  int       r;
93
0
  u8        buf[128];
94
0
  sc_path_t path;
95
0
  sc_card_t *card = p15card->card;
96
97
  /* check if we have the correct card OS */
98
0
  if (strncmp(card->name, "A-TRUST ACOS", strlen("A-TRUST ACOS")))
99
0
    return SC_ERROR_WRONG_CARD;
100
  /* read EF_CIN_CSN file */
101
0
  sc_format_path("DF71D001", &path);
102
0
  r = sc_select_file(card, &path, NULL);
103
0
  if (r != SC_SUCCESS)
104
0
    return SC_ERROR_WRONG_CARD;
105
0
  r = sc_read_binary(card, 0, buf, 8, 0);
106
0
  if (r != 8)
107
0
    return SC_ERROR_WRONG_CARD;
108
109
0
  return SC_SUCCESS;
110
0
}
111
112
static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card)
113
0
{
114
0
  const cdata certs[] = {
115
0
    {"C.CH.EKEY", 0, "DF71C001","1", 0},/* Decryption Certificate */
116
0
    {NULL, 0, NULL, NULL, 0}
117
0
  };
118
119
0
  const pindata pins[] = {
120
0
    { "01", "PIN.DEC", "3F00DF71", 0x81, /* Decryption PIN */
121
0
      SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
122
0
      4, 4, 8, SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
123
0
      SC_PKCS15_PIN_FLAG_LOCAL, -1, 0x00,
124
0
      SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE },
125
0
    { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0}
126
0
  };
127
128
0
  const prdata prkeys[] = {
129
0
    { "01", "SK.CH.EKEY", 1536,
130
0
      SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
131
0
      "", /* do not specify file here to prevent reset of security state */
132
0
      0x88, "01", SC_PKCS15_CO_FLAG_PRIVATE},
133
0
    { NULL, NULL, 0, 0, NULL, 0, NULL, 0}
134
0
  };
135
136
0
  int    r, i;
137
0
  u8     buf[256];
138
0
  char   buf2[256];
139
0
  sc_path_t path;
140
0
  sc_file_t *file = NULL;
141
0
  sc_card_t *card = p15card->card;
142
143
  /* get serial number */
144
145
  /* read EF_CIN_CSN file */
146
0
  sc_format_path("DF71D001", &path);
147
0
  r = sc_select_file(card, &path, NULL);
148
0
  if (r != SC_SUCCESS)
149
0
    return SC_ERROR_INTERNAL;
150
0
  r = sc_read_binary(card, 0, buf, 8, 0);
151
0
  if (r != 8)
152
0
    return SC_ERROR_INTERNAL;
153
0
  r = sc_bin_to_hex(buf, 8, buf2, sizeof(buf2), 0);
154
0
  if (r != SC_SUCCESS)
155
0
    return SC_ERROR_INTERNAL;
156
157
0
  set_string(&p15card->tokeninfo->serial_number, buf2);
158
0
  if (!p15card->tokeninfo->serial_number)
159
0
    return SC_ERROR_INTERNAL;
160
161
  /* manufacturer ID */
162
0
  set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID);
163
0
  if (!p15card->tokeninfo->manufacturer_id)
164
0
    goto err;
165
166
  /* card label */
167
0
  set_string(&p15card->tokeninfo->label, CARD_LABEL);
168
0
  if (!p15card->tokeninfo->label)
169
0
    goto err;
170
171
  /* set certs */
172
0
  for (i = 0; certs[i].label; i++) {
173
0
    struct sc_pkcs15_cert_info cert_info;
174
0
    struct sc_pkcs15_object    cert_obj;
175
176
0
    memset(&cert_info, 0, sizeof(cert_info));
177
0
    memset(&cert_obj,  0, sizeof(cert_obj));
178
179
0
    sc_pkcs15_format_id(certs[i].id, &cert_info.id);
180
0
    cert_info.authority = certs[i].authority;
181
0
    sc_format_path(certs[i].path, &cert_info.path);
182
0
    if (!get_cert_len(card, &cert_info.path))
183
      /* skip errors */
184
0
      continue;
185
186
0
    strlcpy(cert_obj.label, certs[i].label, sizeof(cert_obj.label));
187
0
    cert_obj.flags = certs[i].obj_flags;
188
189
0
    r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
190
0
    if (r < 0)
191
0
      goto err;
192
0
  }
193
  /* set pins */
194
0
  for (i = 0; pins[i].label; i++) {
195
0
    struct sc_pkcs15_auth_info pin_info;
196
0
    struct sc_pkcs15_object   pin_obj;
197
198
0
    memset(&pin_info, 0, sizeof(pin_info));
199
0
    memset(&pin_obj,  0, sizeof(pin_obj));
200
201
0
    sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id);
202
0
    pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
203
0
    pin_info.attrs.pin.reference     = pins[i].ref;
204
0
    pin_info.attrs.pin.flags         = pins[i].flags;
205
0
    pin_info.attrs.pin.type          = pins[i].type;
206
0
    pin_info.attrs.pin.min_length    = pins[i].minlen;
207
0
    pin_info.attrs.pin.stored_length = pins[i].storedlen;
208
0
    pin_info.attrs.pin.max_length    = pins[i].maxlen;
209
0
    pin_info.attrs.pin.pad_char      = pins[i].pad_char;
210
0
    sc_format_path(pins[i].path, &pin_info.path);
211
0
    pin_info.tries_left    = -1;
212
0
    pin_info.logged_in = SC_PIN_STATE_UNKNOWN;
213
214
0
    strlcpy(pin_obj.label, pins[i].label, sizeof(pin_obj.label));
215
0
    pin_obj.flags = pins[i].obj_flags;
216
217
0
    r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
218
0
    if (r < 0)
219
0
      goto err;
220
0
  }
221
  /* set private keys */
222
0
  for (i = 0; prkeys[i].label; i++) {
223
0
    struct sc_pkcs15_prkey_info prkey_info;
224
0
    struct sc_pkcs15_object     prkey_obj;
225
226
0
    memset(&prkey_info, 0, sizeof(prkey_info));
227
0
    memset(&prkey_obj,  0, sizeof(prkey_obj));
228
229
0
    sc_pkcs15_format_id(prkeys[i].id, &prkey_info.id);
230
0
    prkey_info.usage         = prkeys[i].usage;
231
0
    prkey_info.native        = 1;
232
0
    prkey_info.key_reference = prkeys[i].ref;
233
0
    prkey_info.modulus_length= prkeys[i].modulus_len;
234
0
    sc_format_path(prkeys[i].path, &prkey_info.path);
235
236
0
    strlcpy(prkey_obj.label, prkeys[i].label, sizeof(prkey_obj.label));
237
0
    prkey_obj.flags = prkeys[i].obj_flags;
238
0
    if (prkeys[i].auth_id)
239
0
      sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id);
240
241
0
    r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
242
0
    if (r < 0)
243
0
      goto err;
244
0
  }
245
246
  /* select the application DF */
247
0
  sc_format_path("DF71", &path);
248
0
  r = sc_select_file(card, &path, &file);
249
0
  if (r != SC_SUCCESS || !file)
250
0
    goto err;
251
  /* set the application DF */
252
0
  sc_file_free(p15card->file_app);
253
0
  p15card->file_app = file;
254
255
0
  return SC_SUCCESS;
256
257
0
err:
258
0
  sc_pkcs15_card_clear(p15card);
259
0
  return SC_ERROR_INTERNAL;
260
0
}
261
262
int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card,
263
          struct sc_aid *aid)
264
0
{
265
0
  if (acos_detect_card(p15card))
266
0
    return SC_ERROR_WRONG_CARD;
267
0
  return sc_pkcs15emu_atrust_acos_init(p15card);
268
0
}