Coverage Report

Created: 2025-12-07 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15-actalis.c
Line
Count
Source
1
/*
2
 * PKCS15 emulation layer for Actalis card.
3
 * To see how this works, run p15dump on your Actalis Card.
4
 *
5
 * Copyright (C) 2005, Andrea Frigido <andrea@frisoft.it>
6
 * Copyright (C) 2005, Sirio Capizzi <graaf@virgilio.it>
7
 * Copyright (C) 2004, Antonino Iacono <ant_iacono@tin.it>
8
 * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 */
24
25
#ifdef HAVE_CONFIG_H
26
#include "config.h"
27
#endif
28
29
#include <stdlib.h>
30
#include <string.h>
31
#include <stdio.h>
32
#ifdef ENABLE_ZLIB
33
#include <zlib.h>
34
#endif
35
36
#include "common/compat_strlcpy.h"
37
#include "libopensc/pkcs15.h"
38
#include "libopensc/log.h"
39
#include "libopensc/internal.h"
40
41
static int (*set_security_env) (sc_card_t *, const sc_security_env_t *, int);
42
43
static int set_sec_env(sc_card_t * card, const sc_security_env_t *env,
44
           int se_num)
45
0
{
46
0
  int r;
47
0
  sc_security_env_t tenv = *env;
48
0
  if (tenv.operation == SC_SEC_OPERATION_SIGN)
49
0
    tenv.operation = SC_SEC_OPERATION_DECIPHER;
50
51
0
  if ((r =
52
0
       card->ops->restore_security_env(card, 0x40)) == SC_SUCCESS)
53
0
    return set_security_env(card, &tenv, se_num);
54
0
  else
55
0
    return r;
56
0
}
57
58
static int do_sign(sc_card_t * card, const u8 * in, size_t inlen, u8 * out,
59
       size_t outlen)
60
0
{
61
0
  return card->ops->decipher(card, in, inlen, out, outlen);
62
0
}
63
64
#if 1
65
/* XXX: temporary copy of the old pkcs15emu functions,
66
 *      to be removed */
67
static int sc_pkcs15emu_add_pin(sc_pkcs15_card_t *p15card,
68
                const sc_pkcs15_id_t *id, const char *label,
69
                const sc_path_t *path, int ref, int type,
70
                unsigned int min_length,
71
                unsigned int max_length,
72
                int flags, int tries_left, const char pad_char, int obj_flags)
73
0
{
74
0
  sc_pkcs15_auth_info_t info;
75
0
  sc_pkcs15_object_t   obj;
76
77
0
  memset(&info, 0, sizeof(info));
78
0
  memset(&obj,  0, sizeof(obj));
79
80
0
  info.auth_id           = *id;
81
0
  info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
82
0
  info.attrs.pin.min_length        = min_length;
83
0
  info.attrs.pin.max_length        = max_length;
84
0
  info.attrs.pin.stored_length     = max_length;
85
0
  info.attrs.pin.type              = type;
86
0
  info.attrs.pin.reference         = ref;
87
0
  info.attrs.pin.flags             = flags;
88
0
  info.attrs.pin.pad_char          = pad_char;
89
0
  info.tries_left        = tries_left;
90
0
  info.logged_in = SC_PIN_STATE_UNKNOWN;
91
92
0
  if (path)
93
0
    info.path = *path;
94
0
  if (type == SC_PKCS15_PIN_TYPE_BCD)
95
0
    info.attrs.pin.stored_length /= 2;
96
97
0
  strlcpy(obj.label, label, sizeof(obj.label));
98
0
  obj.flags = obj_flags;
99
100
0
  return sc_pkcs15emu_add_pin_obj(p15card, &obj, &info);
101
0
}
102
103
static int sc_pkcs15emu_add_prkey(sc_pkcs15_card_t *p15card,
104
                const sc_pkcs15_id_t *id,
105
                const char *label,
106
                int type, unsigned int modulus_length, int usage,
107
                const sc_path_t *path, int ref,
108
                const sc_pkcs15_id_t *auth_id, int obj_flags)
109
0
{
110
0
        sc_pkcs15_prkey_info_t info;
111
0
  sc_pkcs15_object_t     obj;
112
113
0
  memset(&info, 0, sizeof(info));
114
0
  memset(&obj,  0, sizeof(obj));
115
116
0
        info.id                = *id;
117
0
        info.modulus_length    = modulus_length;
118
0
        info.usage             = usage;
119
0
        info.native            = 1;
120
0
        info.key_reference     = ref;
121
122
0
        if (path)
123
0
                info.path = *path;
124
125
0
  obj.flags = obj_flags;
126
0
  strlcpy(obj.label, label, sizeof(obj.label));
127
0
  if (auth_id != NULL)
128
0
    obj.auth_id = *auth_id;
129
130
0
        return sc_pkcs15emu_add_rsa_prkey(p15card, &obj, &info);
131
0
}
132
#endif
133
134
static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card)
135
0
{
136
0
  sc_card_t *card = p15card->card;
137
0
  sc_path_t path;
138
0
  sc_pkcs15_id_t id, auth_id;
139
0
  unsigned char serial_buf[13], *serial;
140
0
  int flags;
141
0
  int r;
142
143
0
#ifdef ENABLE_ZLIB
144
0
  int use_file_cache_backup = p15card->opts.use_file_cache;
145
146
0
  int i = 0, j = 0;
147
0
  const char *certLabel[] = {
148
0
    "User Non-repudiation Certificate", /* "User Non-repudiation Certificate" */
149
0
    "TSA Certificate",
150
0
    "CA Certificate"
151
0
  };
152
0
  const char *certPath[] =
153
0
      { "3F00300060006002", "3F00300060006003", "3F00300060006004" };
154
0
#endif
155
156
0
  const char *keyPath = "3F00300040000008";
157
0
  const char *pinDfName = "05040200";
158
159
  /* const int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; */
160
0
  const int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN
161
0
        | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
162
0
        | SC_PKCS15_PRKEY_USAGE_ENCRYPT
163
0
        | SC_PKCS15_PRKEY_USAGE_DECRYPT;
164
165
0
  const char *authPIN = "Authentication PIN";
166
  /* const char *nonrepPIN = "Non-repudiation PIN"; */
167
168
0
  const char *authPRKEY = "Authentication Key";
169
  /* const char *nonrepPRKEY = "Non repudiation Key"; */
170
171
0
  p15card->opts.use_file_cache = SC_PKCS15_OPTS_CACHE_ALL_FILES;
172
173
  /* Get Serial number */
174
0
  sc_format_path("3F0030000001", &path);
175
0
  r = sc_select_file(card, &path, NULL);
176
0
  if (r != SC_SUCCESS)
177
0
    return SC_ERROR_WRONG_CARD;
178
179
0
  r = sc_read_binary(card, 0xC3, serial_buf, 12, 0);
180
0
  if (r != SC_SUCCESS)
181
0
    return SC_ERROR_WRONG_CARD;
182
0
  serial = serial_buf;
183
184
  /*
185
   * The serial number is 8 characters long. Later versions of the
186
   * card have the serial number at a different offset, after 4 more
187
   * bytes.
188
   */
189
0
  if (serial[0] != 'H') {
190
0
    if (serial[4] == 'H')
191
0
      serial = &serial_buf[4];
192
0
    else
193
0
      return SC_ERROR_WRONG_CARD;
194
0
  }
195
0
  serial[8] = '\0';
196
197
  /* Controllo che il serial number inizi per "H" */
198
0
  if( serial[0] != 'H' )
199
0
    return SC_ERROR_WRONG_CARD;
200
201
0
  set_string(&p15card->tokeninfo->label, "Actalis");
202
0
  set_string(&p15card->tokeninfo->manufacturer_id, "Actalis");
203
0
  set_string(&p15card->tokeninfo->serial_number, (char *)serial);
204
205
0
#ifdef ENABLE_ZLIB
206
0
  for (i = 0; i < 3; i++) {
207
0
    sc_path_t cpath;
208
0
    sc_format_path(certPath[i], &cpath);
209
210
0
    if (sc_select_file(card, &cpath, NULL) == SC_SUCCESS) {
211
0
      unsigned char *compCert = NULL, *cert = NULL, size[2];
212
0
      unsigned long compLen, len;
213
214
0
      sc_pkcs15_cert_info_t cert_info;
215
0
      sc_pkcs15_object_t cert_obj;
216
0
      memset(&cert_info, 0, sizeof(cert_info));
217
0
      memset(&cert_obj, 0, sizeof(cert_obj));
218
219
0
      if (SC_SUCCESS != sc_read_binary(card, 2, size, 2, 0))
220
0
        continue;
221
0
      compLen = (size[0] << 8) + size[1];
222
0
      compCert = malloc(compLen * sizeof(unsigned char));
223
0
      len = 3 * compLen;  /*Approximation of the uncompressed size */
224
0
      cert = malloc(len * sizeof(unsigned char));
225
0
      if (!cert || !compCert) {
226
0
        free(cert);
227
0
        free(compCert);
228
0
        sc_pkcs15_card_clear(p15card);
229
0
        p15card->opts.use_file_cache = use_file_cache_backup;
230
0
        return SC_ERROR_OUT_OF_MEMORY;
231
0
      }
232
233
0
      if (sc_read_binary(card, 4, compCert, compLen, 0) != SC_SUCCESS
234
0
          || uncompress(cert, &len, compCert, compLen) != Z_OK) {
235
0
        free(cert);
236
0
        free(compCert);
237
0
        continue;
238
0
      }
239
0
      cpath.index = 0;
240
0
      cpath.count = (int)len;
241
242
0
      sc_pkcs15_cache_file(p15card, &cpath, cert, len);
243
0
      id.value[0] = j + 1;
244
0
      id.len = 1;
245
0
      cert_info.id = id;
246
0
      cert_info.path = cpath;
247
0
      cert_info.authority = (j>0);
248
249
0
      strlcpy(cert_obj.label, certLabel[j], sizeof(cert_obj.label));
250
251
0
      j++;
252
0
      cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
253
0
      r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
254
0
      if (r < 0) {
255
0
        sc_log(card->ctx, "Failed to add cert obj r=%d", r);
256
0
        free(cert);
257
0
        free(compCert);
258
0
        continue;
259
0
      }
260
261
0
      free(cert);
262
0
      free(compCert);
263
0
    }
264
0
  }
265
0
#endif
266
267
  /* adding PINs & private keys */
268
0
  flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
269
0
      SC_PKCS15_PIN_FLAG_INITIALIZED |
270
0
      SC_PKCS15_PIN_FLAG_NEEDS_PADDING;
271
272
0
  sc_format_path(pinDfName, &path);
273
0
  path.type = SC_PATH_TYPE_DF_NAME;
274
275
0
  id.value[0] = 1;
276
0
  id.len = 1;
277
0
  sc_pkcs15emu_add_pin(p15card, &id,
278
0
           authPIN, &path, 0x81,
279
0
           SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
280
0
           5, 8, flags, 3, 0,
281
0
           SC_PKCS15_CO_FLAG_MODIFIABLE |
282
0
           SC_PKCS15_CO_FLAG_PRIVATE);
283
284
0
  sc_format_path(keyPath, &path);
285
0
  id.value[0] = 1;
286
0
  id.len = 1;
287
0
  auth_id.value[0] = 1;
288
0
  auth_id.len = 1;
289
0
  sc_pkcs15emu_add_prkey(p15card, &id,
290
0
           authPRKEY,
291
0
           SC_PKCS15_TYPE_PRKEY_RSA,
292
0
           1024, authprkey_usage,
293
0
           &path, 0x08,
294
0
           &auth_id,
295
0
           SC_PKCS15_CO_FLAG_PRIVATE);
296
297
  /* return to MF */
298
0
  sc_format_path("3F00", &path);
299
0
  sc_select_file(card, &path, NULL);
300
0
  {
301
    /* save old signature funcs */
302
0
    set_security_env = card->ops->set_security_env;
303
    /* set new one             */
304
0
    card->ops->set_security_env  = set_sec_env;
305
0
    card->ops->compute_signature = do_sign;
306
0
  }
307
308
0
  return SC_SUCCESS;
309
310
0
}
311
312
static int actalis_detect_card(sc_pkcs15_card_t * p15card)
313
0
{
314
0
  sc_card_t *card = p15card->card;
315
316
  /* check if we have the correct card OS */
317
0
  if (strcmp(card->name, "CardOS M4"))
318
0
    return SC_ERROR_WRONG_CARD;
319
320
0
  return SC_SUCCESS;
321
0
}
322
323
int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t * p15card,
324
         struct sc_aid *aid)
325
0
{
326
0
  if (actalis_detect_card(p15card))
327
0
    return SC_ERROR_WRONG_CARD;
328
0
  return sc_pkcs15emu_actalis_init(p15card);
329
0
}