Coverage Report

Created: 2025-07-18 06:10

/src/opensc/src/pkcs15init/pkcs15-sc-hsm.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * pkcs15-sc-hsm.c : PKCS#15 emulation for write support
3
 *
4
 * Copyright (C) 2012 Andreas Schwier, CardContact, Minden, Germany
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
21
#ifdef HAVE_CONFIG_H
22
#include <config.h>
23
#endif
24
25
#include <stdlib.h>
26
#include <string.h>
27
#include <sys/types.h>
28
#include <ctype.h>
29
#include <errno.h>
30
#include <stdio.h>
31
32
#include "../libopensc/opensc.h"
33
#include "../libopensc/cardctl.h"
34
#include "../libopensc/log.h"
35
#include "../libopensc/pkcs15.h"
36
#include "../libopensc/cards.h"
37
#include "../libopensc/card-sc-hsm.h"
38
#include "../libopensc/asn1.h"
39
#include "../libopensc/pkcs15.h"
40
41
#include "common/compat_strlcpy.h"
42
#include "common/compat_strlcat.h"
43
44
#include "pkcs15-init.h"
45
#include "profile.h"
46
47
48
49
static u8 pubexp[] = { 0x01, 0x00, 0x01 };
50
51
52
53
static int sc_hsm_delete_ef(sc_pkcs15_card_t *p15card, u8 prefix, u8 id)
54
0
{
55
0
  sc_card_t *card = p15card->card;
56
0
  sc_path_t path;
57
0
  u8 fid[2];
58
0
  int r;
59
60
0
  fid[0] = prefix;
61
0
  fid[1] = id;
62
63
0
  sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, -1);
64
65
0
  r = sc_delete_file(card, &path);
66
0
  LOG_TEST_RET(card->ctx, r, "Could not delete file");
67
68
0
  LOG_FUNC_RETURN(card->ctx, r);
69
0
}
70
71
72
73
static int sc_hsm_update_ef(sc_pkcs15_card_t *p15card, u8 prefix, u8 id, int erase, u8 *buf, size_t buflen)
74
422
{
75
422
  sc_card_t *card = p15card->card;
76
422
  sc_file_t *file = NULL;
77
422
  sc_path_t path;
78
422
  u8 fid[2];
79
422
  int r;
80
81
422
  fid[0] = prefix;
82
422
  fid[1] = id;
83
84
422
  sc_path_set(&path, SC_PATH_TYPE_FILE_ID, fid, 2, 0, -1);
85
86
422
  r = sc_select_file(card, &path, NULL);
87
88
422
  if ((r == SC_SUCCESS) && erase) {
89
12
    r = sc_delete_file(card, &path);
90
12
    LOG_TEST_RET(card->ctx, r, "Could not delete file");
91
5
    r = SC_ERROR_FILE_NOT_FOUND;
92
5
  }
93
94
415
  if (r == SC_ERROR_FILE_NOT_FOUND) {
95
7
    file = sc_file_new();
96
7
    file->id = (path.value[0] << 8) | path.value[1];
97
7
    file->type = SC_FILE_TYPE_WORKING_EF;
98
7
    file->ef_structure = SC_FILE_EF_TRANSPARENT;
99
7
    file->size = (size_t) 0;
100
7
    file->status = SC_FILE_STATUS_ACTIVATED;
101
7
    r = sc_create_file(card, file);
102
7
    sc_file_free(file);
103
7
    LOG_TEST_RET(card->ctx, r, "Could not create file");
104
7
  }
105
106
415
  r = sc_update_binary(card, 0, buf, buflen, 0);
107
415
  LOG_FUNC_RETURN(card->ctx, r);
108
415
}
109
110
111
112
static int sc_hsm_create_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
113
  sc_pkcs15_object_t *obj)
114
1.85k
{
115
  // Keys are automatically generated in GENERATE ASYMMETRIC KEY PAIR command
116
1.85k
  LOG_FUNC_CALLED(p15card->card->ctx);
117
1.85k
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
118
1.85k
}
119
120
121
122
static int sc_hsm_store_key(sc_profile_t *profile, sc_pkcs15_card_t *p15card,
123
  sc_pkcs15_object_t *obj, sc_pkcs15_prkey_t *key)
124
1.11k
{
125
1.11k
  LOG_FUNC_CALLED(p15card->card->ctx);
126
1.11k
  LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_NOT_SUPPORTED);
127
1.11k
}
128
129
130
131
static int sc_hsm_determine_free_id(struct sc_pkcs15_card *p15card, u8 range)
132
1.12k
{
133
1.12k
  struct sc_card *card = p15card->card;
134
1.12k
  u8 filelist[MAX_EXT_APDU_LENGTH];
135
1.12k
  int filelistlength, i, j;
136
137
1.12k
  LOG_FUNC_CALLED(p15card->card->ctx);
138
139
1.12k
  filelistlength = sc_list_files(card, filelist, sizeof(filelist));
140
1.12k
  LOG_TEST_RET(card->ctx, filelistlength, "Could not enumerate file and key identifier");
141
142
17.2k
  for (j = 0; j < 256; j++) {
143
351k
    for (i = 0; i + 1 < filelistlength; i += 2) {
144
334k
      if ((filelist[i] == range) && (filelist[i + 1] == j)) {
145
116
        break;
146
116
      }
147
334k
    }
148
17.2k
    if (i >= filelistlength) {
149
1.05k
      LOG_FUNC_RETURN(p15card->card->ctx, j);
150
1.05k
    }
151
17.2k
  }
152
63
  LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_NOT_ENOUGH_MEMORY);
153
63
}
154
155
156
157
356
static int sc_hsm_encode_gakp_rsa(struct sc_pkcs15_card *p15card, sc_cvc_t *cvc, size_t keysize) {
158
356
  struct sc_object_id rsa15withSHA256 = { { 0,4,0,127,0,7,2,2,2,1,2,-1 } };
159
160
356
  LOG_FUNC_CALLED(p15card->card->ctx);
161
162
356
  cvc->coefficientAorExponentlen = sizeof(pubexp);
163
356
  cvc->coefficientAorExponent = malloc(sizeof(pubexp));
164
356
  if (!cvc->coefficientAorExponent) {
165
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
166
0
  }
167
356
  memcpy(cvc->coefficientAorExponent, pubexp, sizeof(pubexp));
168
169
356
  cvc->pukoid = rsa15withSHA256;
170
356
  cvc->modulusSize = (int)keysize;
171
172
356
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
173
356
}
174
175
176
177
363
static int sc_hsm_encode_gakp_ec(struct sc_pkcs15_card *p15card, sc_cvc_t *cvc, struct sc_pkcs15_prkey_info *key_info) {
178
363
  struct sc_object_id ecdsaWithSHA256 = { { 0,4,0,127,0,7,2,2,2,2,3,-1 } };
179
363
  struct sc_ec_parameters *ecparams = (struct sc_ec_parameters *)key_info->params.data;
180
363
  struct ec_curve *curve = NULL;
181
363
  u8 *curveoid;
182
363
  int curveoidlen,r;
183
184
363
  LOG_FUNC_CALLED(p15card->card->ctx);
185
186
363
  curveoid = ecparams->der.value;
187
363
  if ((ecparams->der.len < 3) || (*curveoid++ != 0x06)) {
188
0
    sc_log(p15card->card->ctx, "EC_PARAMS does not contain curve object identifier");
189
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_DATA);
190
0
  }
191
192
363
  curveoidlen = *curveoid++;
193
194
363
  r = sc_pkcs15emu_sc_hsm_get_curve(&curve, curveoid, curveoidlen);
195
363
  LOG_TEST_RET(p15card->card->ctx, r, "Unsupported named curve");
196
197
363
  cvc->primeOrModuluslen = curve->prime.len;
198
363
  cvc->primeOrModulus = malloc(cvc->primeOrModuluslen);
199
363
  if (!cvc->primeOrModulus) {
200
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
201
0
  }
202
363
  memcpy(cvc->primeOrModulus, curve->prime.value, cvc->primeOrModuluslen);
203
204
363
  cvc->coefficientAorExponentlen = curve->coefficientA.len;
205
363
  cvc->coefficientAorExponent = malloc(cvc->coefficientAorExponentlen);
206
363
  if (!cvc->coefficientAorExponent) {
207
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
208
0
  }
209
363
  memcpy(cvc->coefficientAorExponent, curve->coefficientA.value, cvc->coefficientAorExponentlen);
210
211
363
  cvc->coefficientBlen = curve->coefficientB.len;
212
363
  cvc->coefficientB = malloc(cvc->coefficientBlen);
213
363
  if (!cvc->coefficientB) {
214
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
215
0
  }
216
363
  memcpy(cvc->coefficientB, curve->coefficientB.value, cvc->coefficientBlen);
217
218
363
  cvc->basePointGlen = curve->basePointG.len;
219
363
  cvc->basePointG = malloc(cvc->basePointGlen);
220
363
  if (!cvc->basePointG) {
221
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
222
0
  }
223
363
  memcpy(cvc->basePointG, curve->basePointG.value, cvc->basePointGlen);
224
225
363
  cvc->orderlen = curve->order.len;
226
363
  cvc->order = malloc(cvc->orderlen);
227
363
  if (!cvc->order) {
228
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
229
0
  }
230
363
  memcpy(cvc->order, curve->order.value, cvc->orderlen);
231
232
363
  cvc->cofactorlen = curve->coFactor.len;
233
363
  cvc->cofactor = malloc(cvc->cofactorlen);
234
363
  if (!cvc->cofactor) {
235
0
    LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_OUT_OF_MEMORY);
236
0
  }
237
363
  memcpy(cvc->cofactor, curve->coFactor.value, cvc->cofactorlen);
238
239
363
  cvc->pukoid = ecdsaWithSHA256;
240
241
363
  LOG_FUNC_RETURN(p15card->card->ctx, SC_SUCCESS);
242
363
}
243
244
245
246
static int sc_hsm_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
247
                              struct sc_pkcs15_object *object,
248
                              struct sc_pkcs15_pubkey *pubkey)
249
742
{
250
742
  struct sc_card *card = p15card->card;
251
742
  sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
252
742
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
253
742
  sc_cardctl_sc_hsm_keygen_info_t sc_hsm_keyinfo;
254
742
  sc_cvc_t cvc;
255
742
  u8 *cvcbin, *cvcpo;
256
742
  unsigned int cla,tag;
257
742
  size_t taglen, cvclen;
258
742
  int r;
259
260
742
  LOG_FUNC_CALLED(p15card->card->ctx);
261
262
742
  key_info->key_reference = sc_hsm_determine_free_id(p15card, KEY_PREFIX);
263
742
  LOG_TEST_RET(card->ctx, key_info->key_reference, "Could not determine key reference");
264
265
719
  memset(&cvc, 0, sizeof(cvc));
266
267
719
  strlcpy(cvc.car, "UTCA00001", sizeof cvc.car);
268
719
  cvc.carLen = strlen(cvc.car);
269
719
  if (priv->serialno)
270
0
    strlcpy(cvc.chr, priv->serialno, sizeof cvc.chr);
271
719
  strlcat(cvc.chr, "00001", sizeof cvc.chr);
272
719
  cvc.chrLen = strlen(cvc.chr);
273
274
719
  switch(object->type) {
275
356
  case SC_PKCS15_TYPE_PRKEY_RSA:
276
356
    r = sc_hsm_encode_gakp_rsa(p15card, &cvc, key_info->modulus_length);
277
356
    break;
278
363
  case SC_PKCS15_TYPE_PRKEY_EC:
279
363
    r = sc_hsm_encode_gakp_ec(p15card, &cvc, key_info);
280
363
    break;
281
0
  default:
282
0
    r = SC_ERROR_NOT_IMPLEMENTED;
283
0
    break;
284
719
  }
285
719
  if (r != SC_SUCCESS) {
286
0
    sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
287
0
    LOG_TEST_RET(p15card->card->ctx, r, "Could not encode GAKP cdata");
288
0
  }
289
290
719
  r = sc_pkcs15emu_sc_hsm_encode_cvc(p15card, &cvc, &cvcbin, &cvclen);
291
719
  sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
292
719
  LOG_TEST_RET(p15card->card->ctx, r, "Could not encode GAKP cdata");
293
294
295
719
  cvcpo = cvcbin;
296
719
  sc_asn1_read_tag((const u8 **)&cvcpo, cvclen, &cla, &tag, &taglen);
297
719
  sc_asn1_read_tag((const u8 **)&cvcpo, cvclen, &cla, &tag, &taglen);
298
299
719
  sc_hsm_keyinfo.key_id = key_info->key_reference;
300
719
  sc_hsm_keyinfo.auth_key_id = 0;
301
719
  sc_hsm_keyinfo.gakprequest = cvcpo;
302
719
  sc_hsm_keyinfo.gakprequest_len = taglen;
303
719
  sc_hsm_keyinfo.gakpresponse = NULL;
304
719
  sc_hsm_keyinfo.gakpresponse_len = 0;
305
306
719
  r = sc_card_ctl(card, SC_CARDCTL_SC_HSM_GENERATE_KEY, &sc_hsm_keyinfo);
307
719
  if (r < 0)
308
687
    goto out;
309
310
311
32
  cvcpo = sc_hsm_keyinfo.gakpresponse;
312
32
  cvclen = sc_hsm_keyinfo.gakpresponse_len;
313
314
32
  r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&cvcpo, &cvclen, &cvc);
315
32
  if (r < 0) {
316
32
    sc_log(p15card->card->ctx, "Could not decode GAKP rdata");
317
32
    r = SC_ERROR_OBJECT_NOT_VALID;
318
32
    goto out;
319
32
  }
320
321
0
  r = sc_hsm_update_ef(p15card, EE_CERTIFICATE_PREFIX, key_info->key_reference, 1, sc_hsm_keyinfo.gakpresponse, sc_hsm_keyinfo.gakpresponse_len);
322
0
  if (r < 0) {
323
0
    sc_log(p15card->card->ctx, "Could not save certificate signing request");
324
0
    goto out;
325
0
  }
326
327
0
  if (pubkey != NULL) {
328
0
    r = sc_pkcs15emu_sc_hsm_get_public_key(p15card->card->ctx, &cvc, pubkey);
329
0
  }
330
331
719
  out:
332
333
719
  sc_pkcs15emu_sc_hsm_free_cvc(&cvc);
334
335
719
  if (cvcbin) {
336
719
    free(cvcbin);
337
719
  }
338
719
  if (sc_hsm_keyinfo.gakpresponse) {
339
32
    free(sc_hsm_keyinfo.gakpresponse);
340
32
  }
341
719
  LOG_FUNC_RETURN(p15card->card->ctx, r);
342
719
}
343
344
345
346
/*
347
 * Certificates with a related private key are stored in the fid range CE00 - CEFF. The
348
 * second byte in the fid matches the key id.
349
 * Certificates without a related private key (e.g. CA certificates) are stored in the fid range
350
 * CA00 - CAFF. The second byte is a free selected id.
351
 */
352
static int sc_hsm_emu_store_cert(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
353
    struct sc_pkcs15_object *object,
354
    struct sc_pkcs15_der *data)
355
356
0
{
357
0
  struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) object->data;
358
0
  struct sc_pkcs15_object *prkey;
359
0
  sc_path_t path;
360
0
  u8 id[2];
361
0
  int r;
362
363
0
  r = sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PRKEY, &cert_info->id , &prkey);
364
365
0
  if (r == SC_ERROR_OBJECT_NOT_FOUND) {
366
0
    r = sc_hsm_determine_free_id(p15card, CA_CERTIFICATE_PREFIX);
367
0
    LOG_TEST_RET(p15card->card->ctx, r, "Out of identifier to store certificate description");
368
369
0
    id[0] = CA_CERTIFICATE_PREFIX;
370
0
    id[1] = r;
371
0
  } else {
372
0
    LOG_TEST_RET(p15card->card->ctx, r, "Error locating matching private key");
373
374
0
    id[0] = EE_CERTIFICATE_PREFIX;
375
0
    id[1] = ((struct sc_pkcs15_prkey_info *)prkey->data)->key_reference;
376
0
  }
377
378
0
  sc_path_set(&path, SC_PATH_TYPE_FILE_ID, id, 2, 0, -1);
379
0
  cert_info->path = path;
380
381
0
  r = sc_hsm_update_ef(p15card, id[0], id[1], 1, data->value, data->len);
382
0
  return r;
383
0
}
384
385
386
387
static int sc_hsm_emu_delete_cert(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
388
    struct sc_pkcs15_object *object)
389
390
0
{
391
0
  struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) object->data;
392
393
0
  return sc_hsm_delete_ef(p15card, cert_info->path.value[0], cert_info->path.value[1]);
394
0
}
395
396
397
398
static int sc_hsm_emu_store_binary(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
399
    struct sc_pkcs15_object *object,
400
    struct sc_pkcs15_der *data)
401
402
382
{
403
382
  struct sc_pkcs15_data_info *data_info = (struct sc_pkcs15_data_info *) object->data;
404
382
  sc_path_t path;
405
382
  u8 id[2];
406
382
  int r;
407
408
382
  r = sc_hsm_determine_free_id(p15card, DCOD_PREFIX);
409
382
  LOG_TEST_RET(p15card->card->ctx, r, "Out of identifier to store data description");
410
411
336
  if (object->flags & SC_PKCS15_CO_FLAG_PRIVATE) {
412
0
    id[0] = PROT_DATA_PREFIX;
413
336
  } else {
414
336
    id[0] = DATA_PREFIX;
415
336
  }
416
336
  id[1] = r;
417
418
336
  sc_path_set(&path, SC_PATH_TYPE_FILE_ID, id, 2, 0, -1);
419
336
  data_info->path = path;
420
421
336
  r = sc_hsm_update_ef(p15card, id[0], id[1], 1, data->value, data->len);
422
336
  return r;
423
382
}
424
425
426
427
static int sc_hsm_emu_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
428
    struct sc_pkcs15_object *object,
429
    struct sc_pkcs15_der *data, struct sc_path *path)
430
431
382
{
432
382
  struct sc_context *ctx = p15card->card->ctx;
433
382
  int r;
434
435
382
  LOG_FUNC_CALLED(ctx);
436
437
382
  switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) {
438
0
  case SC_PKCS15_TYPE_PRKEY:
439
0
  case SC_PKCS15_TYPE_PUBKEY:
440
0
    r = SC_SUCCESS;
441
0
    break;
442
0
  case SC_PKCS15_TYPE_CERT:
443
0
    r = sc_hsm_emu_store_cert(p15card, profile, object, data);
444
0
    break;
445
382
  case SC_PKCS15_TYPE_DATA_OBJECT:
446
382
    r = sc_hsm_emu_store_binary(p15card, profile, object, data);
447
382
    break;
448
0
  default:
449
0
    r = SC_ERROR_NOT_IMPLEMENTED;
450
0
    break;
451
382
  }
452
453
382
  LOG_FUNC_RETURN(ctx, r);
454
382
}
455
456
457
458
static int sc_hsm_emu_delete_object(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
459
    struct sc_pkcs15_object *object, const struct sc_path *path)
460
0
{
461
0
  struct sc_context *ctx = p15card->card->ctx;
462
0
  int r;
463
464
0
  LOG_FUNC_CALLED(ctx);
465
466
0
  switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) {
467
0
  case SC_PKCS15_TYPE_PRKEY:
468
0
    r = sc_hsm_delete_ef(p15card, KEY_PREFIX, ((struct sc_pkcs15_prkey_info *)object->data)->key_reference);
469
0
    break;
470
0
  case SC_PKCS15_TYPE_CERT:
471
0
    r = sc_hsm_emu_delete_cert(p15card, profile, object);
472
0
    break;
473
0
  case SC_PKCS15_TYPE_DATA_OBJECT:
474
0
    r = sc_delete_file(p15card->card, path);
475
0
    break;
476
0
  case SC_PKCS15_TYPE_PUBKEY:
477
0
    r = SC_SUCCESS;
478
0
    break;
479
0
  default:
480
0
    r = SC_ERROR_NOT_IMPLEMENTED;
481
0
    break;
482
0
  }
483
484
0
  LOG_FUNC_RETURN(ctx, r);
485
0
}
486
487
488
489
static int sc_hsm_emu_update_prkd(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
490
    struct sc_pkcs15_object *object)
491
0
{
492
0
  struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)object->data;
493
0
  u8 *buf;
494
0
  size_t buflen;
495
0
  int r;
496
497
  // Don't save AID in PRKD
498
0
  key_info->path.aid.len = 0;
499
500
0
  r = sc_pkcs15_encode_prkdf_entry(p15card->card->ctx, object, &buf, &buflen);
501
0
  LOG_TEST_RET(p15card->card->ctx, r, "Error encoding PRKD entry");
502
503
0
  r = sc_hsm_update_ef(p15card, PRKD_PREFIX, key_info->key_reference, 0, buf, buflen);
504
0
  free(buf);
505
0
  return r;
506
0
}
507
508
509
510
static int sc_hsm_emu_update_dcod(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
511
    struct sc_pkcs15_object *object)
512
121
{
513
121
  struct sc_pkcs15_data_info *data_info = (struct sc_pkcs15_data_info *) object->data;
514
121
  u8 *buf;
515
121
  size_t buflen;
516
121
  int r;
517
518
121
  r = sc_pkcs15_encode_dodf_entry(p15card->card->ctx, object, &buf, &buflen);
519
121
  LOG_TEST_RET(p15card->card->ctx, r, "Error encoding DCOD entry");
520
521
86
  r = sc_hsm_update_ef(p15card, DCOD_PREFIX, data_info->path.value[data_info->path.len - 1], 0, buf, buflen);
522
86
  free(buf);
523
86
  return r;
524
121
}
525
526
527
528
static int sc_hsm_emu_update_cd(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
529
    struct sc_pkcs15_object *object)
530
0
{
531
0
  struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) object->data;
532
0
  u8 *buf;
533
0
  size_t buflen;
534
0
  int r;
535
536
0
  if ((cert_info->path.len < 2) ||
537
0
    ((cert_info->path.value[cert_info->path.len - 2]) != CA_CERTIFICATE_PREFIX)) {
538
    // Certificates associated with stored private keys don't get a separate CD entry
539
0
    return SC_SUCCESS;
540
0
  }
541
542
0
  r = sc_pkcs15_encode_cdf_entry(p15card->card->ctx, object, &buf, &buflen);
543
0
  LOG_TEST_RET(p15card->card->ctx, r, "Error encoding CD entry");
544
545
0
  r = sc_hsm_update_ef(p15card, CD_PREFIX, cert_info->path.value[cert_info->path.len - 1], 0, buf, buflen);
546
0
  free(buf);
547
0
  return r;
548
0
}
549
550
551
552
static int sc_hsm_emu_delete_cd(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
553
    struct sc_pkcs15_object *object)
554
0
{
555
0
  struct sc_pkcs15_cert_info *cert_info = (struct sc_pkcs15_cert_info *) object->data;
556
557
0
  if ((cert_info->path.len < 2) ||
558
0
    ((cert_info->path.value[cert_info->path.len - 2]) != CA_CERTIFICATE_PREFIX)) {
559
    // Certificates associated with stored private keys don't get a separate CD entry
560
0
    return SC_SUCCESS;
561
0
  }
562
563
0
  return sc_hsm_delete_ef(p15card, CD_PREFIX, cert_info->path.value[cert_info->path.len - 1]);
564
0
}
565
566
567
568
static int sc_hsm_emu_update_any_df(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
569
    unsigned op, struct sc_pkcs15_object *object)
570
124
{
571
124
  struct sc_context *ctx = p15card->card->ctx;
572
124
  int rv = SC_ERROR_NOT_SUPPORTED;
573
574
124
  SC_FUNC_CALLED(ctx, 1);
575
124
  switch(op)   {
576
0
  case SC_AC_OP_ERASE:
577
0
    sc_log(ctx, "Update DF; erase object('%s',type:%X)", object->label, object->type);
578
0
    switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) {
579
0
    case SC_PKCS15_TYPE_PRKEY:
580
0
      rv = sc_hsm_delete_ef(p15card, PRKD_PREFIX, ((struct sc_pkcs15_prkey_info *)object->data)->key_reference);
581
0
      break;
582
0
    case SC_PKCS15_TYPE_PUBKEY:
583
0
      rv = SC_SUCCESS;
584
0
      break;
585
0
    case SC_PKCS15_TYPE_CERT:
586
0
      rv = sc_hsm_emu_delete_cd(profile, p15card, object);
587
0
      break;
588
0
    case SC_PKCS15_TYPE_DATA_OBJECT:
589
0
      rv = sc_hsm_delete_ef(p15card, DCOD_PREFIX, ((struct sc_pkcs15_data_info *)object->data)->path.value[1]);
590
0
      break;
591
0
    }
592
0
    break;
593
0
  case SC_AC_OP_UPDATE:
594
124
  case SC_AC_OP_CREATE:
595
124
    sc_log(ctx, "Update DF; create object('%s',type:%X)", object->label, object->type);
596
124
    switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) {
597
0
    case SC_PKCS15_TYPE_PUBKEY:
598
0
      rv = SC_SUCCESS;
599
0
      break;
600
0
    case SC_PKCS15_TYPE_PRKEY:
601
0
      rv = sc_hsm_emu_update_prkd(profile, p15card, object);
602
0
      break;
603
0
    case SC_PKCS15_TYPE_CERT:
604
0
      rv = sc_hsm_emu_update_cd(profile, p15card, object);
605
0
      break;
606
121
    case SC_PKCS15_TYPE_DATA_OBJECT:
607
121
      rv = sc_hsm_emu_update_dcod(profile, p15card, object);
608
121
      break;
609
124
    }
610
124
    break;
611
124
  }
612
124
  SC_FUNC_RETURN(ctx, 1, rv);
613
124
}
614
615
616
617
static struct sc_pkcs15init_operations
618
sc_pkcs15init_sc_hsm_operations = {
619
  NULL,             /* erase_card */
620
  NULL,           /* init_card  */
621
  NULL,           /* create_dir */
622
  NULL,           /* create_domain */
623
  NULL,           /* select_pin_reference */
624
  NULL,           /* create_pin */
625
  NULL,           /* select key reference */
626
  sc_hsm_create_key,
627
  sc_hsm_store_key,
628
  sc_hsm_generate_key,
629
  NULL,           /* encode private key */
630
  NULL,           /* encode public key */
631
  NULL,           /* finalize_card */
632
  sc_hsm_emu_delete_object, /* delete object */
633
  NULL,           /* pkcs15init emulation update_dir */
634
  sc_hsm_emu_update_any_df, /* pkcs15init emulation update_any_df */
635
  NULL,           /* pkcs15init emulation update_tokeninfo */
636
  NULL,           /* pkcs15init emulation write_info */
637
  sc_hsm_emu_store_data,
638
  NULL,           /* sanity_check */
639
};
640
641
642
struct sc_pkcs15init_operations *
643
sc_pkcs15init_get_sc_hsm_ops(void)
644
701
{
645
701
  return &sc_pkcs15init_sc_hsm_operations;
646
701
}
647