Coverage Report

Created: 2025-07-01 06:08

/src/opensc/src/libopensc/pkcs15-piv.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * partial PKCS15 emulation for PIV-II cards
3
 * only minimal use of the authentication cert and key
4
 *
5
 * Copyright (C) 2005,2006,2007,2008,2009,2010
6
 *               Douglas E. Engert <deengert@anl.gov>
7
 * Copyright (C) 2020 Douglas E. Engert <deengert@gmail.com>
8
 *               2004, Nils Larsch <larsch@trustcenter.de>
9
 * Copyright (C) 2006, Identity Alliance,
10
 *               Thomas Harning <thomas.harning@identityalliance.com>
11
 * Copyright (C) 2007, EMC, Russell Larner <rlarner@rsa.com>
12
 *
13
 * This library is free software; you can redistribute it and/or
14
 * modify it under the terms of the GNU Lesser General Public
15
 * License as published by the Free Software Foundation; either
16
 * version 2.1 of the License, or (at your option) any later version.
17
 *
18
 * This library is distributed in the hope that it will be useful,
19
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21
 * Lesser General Public License for more details.
22
 *
23
 * You should have received a copy of the GNU Lesser General Public
24
 * License along with this library; if not, write to the Free Software
25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
26
 */
27
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
#endif
31
32
#include <stdlib.h>
33
#include <string.h>
34
#include <stdio.h>
35
#include <ctype.h>
36
37
#include "internal.h"
38
#include "cardctl.h"
39
#include "asn1.h"
40
#include "pkcs15.h"
41
42
0
#define MANU_ID   "piv_II "
43
44
typedef struct objdata_st {
45
  const char *id;
46
  const char *label;
47
  const char *aoid;
48
  const char *auth_id;
49
  const char *path;
50
  int         obj_flags;
51
} objdata;
52
53
typedef struct cdata_st {
54
  const char *id;
55
  const char *label;
56
  const char *path;
57
  int     authority;
58
  int         obj_flags;
59
} cdata;
60
61
typedef struct pdata_st {
62
  const char *id;
63
  const char *label;
64
  const char *path;
65
  int         ref;
66
  int         type;
67
  unsigned int maxlen;
68
  unsigned int minlen;
69
  unsigned int storedlen;
70
  int         flags;
71
  int         tries_left;
72
  const unsigned char  pad_char;
73
  int         obj_flags;
74
  int         cardmod; /* only use with cardmod minidriver */
75
} pindata;
76
77
typedef struct pubdata_st {
78
  const char *id;
79
  const char *label;
80
  int         usage_rsa;
81
  int         usage_ec;
82
  const char *path;
83
  int         ref;
84
  const char *auth_id;
85
  int         obj_flags;
86
  const char *getenvname;
87
} pubdata;
88
89
typedef struct prdata_st {
90
  const char *id;
91
  const char *label;
92
  int         usage_rsa;
93
  int     usage_ec;
94
  const char *path;
95
  int         ref;
96
  const char *auth_id;
97
  int         obj_flags;
98
  int     user_consent;
99
} prdata;
100
101
typedef struct common_key_info_st {
102
  int cert_found;
103
  int pubkey_found;
104
  int pubkey_from_file;
105
  unsigned long key_alg;
106
  size_t pubkey_len;
107
  unsigned int cert_keyUsage; /* x509 key usage as defined in certificate */
108
  int cert_keyUsage_present; /* 1 if keyUsage found in certificate */
109
  int pub_usage;
110
  int priv_usage;
111
  struct sc_pkcs15_pubkey *pubkey_from_cert;
112
  int not_present;
113
} common_key_info;
114
115
116
/*
117
 * The PIV applet has no serial number, and so the either the FASC-N
118
 * is used, or the GUID is used as a serial number.
119
 * We need to return a GUID like value for each object
120
 * But this needs to be some what unique.
121
 * So we will use two different methods, depending
122
 * on the size of the serial number.
123
 * If it is 25 bytes, then it was from a FASCN. If 16 bytes
124
 * its from a GUID.
125
 * If neither, we will uase the default method.
126
 */
127
128
static int piv_get_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
129
    unsigned char *out, size_t *out_size)
130
0
{
131
0
  struct sc_serial_number serialnr;
132
0
  struct sc_pkcs15_id  id;
133
0
  unsigned char guid_bin[SC_PKCS15_MAX_ID_SIZE + SC_MAX_SERIALNR];
134
0
  size_t bin_size, offs, tlen, i;
135
0
  int r;
136
0
  unsigned char fbit, fbits, fbyte, fbyte2, fnibble;
137
0
  unsigned char *f5p, *f8p;
138
139
0
  if (!p15card || !obj || !out || *out_size < 3)
140
0
    return SC_ERROR_INCORRECT_PARAMETERS;
141
142
0
  r = sc_pkcs15_get_object_id(obj, &id);
143
0
  if (r)
144
0
    return r;
145
146
0
  r = sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serialnr);
147
0
  if (r)
148
0
    return r;
149
0
  if (serialnr.len > SC_MAX_SERIALNR)
150
0
    return SC_ERROR_INTERNAL;
151
152
0
  memset(guid_bin, 0, sizeof(guid_bin));
153
0
  memset(out, 0, *out_size);
154
155
0
  if (id.len == 1 && serialnr.len == 25) {
156
157
    /* It is from a FASCN, and we need to shorten it but keep
158
     * as much uniqueness as possible.
159
     * FASC-N is stored like a ISO 7811 Magnetic Strip Card
160
     * Using the ANSI/ISO BCD Data Format
161
     * 4 data bit + 1 parity bit (odd) least significant bit first.
162
     * It starts with the Start Sentinel 0x0b ";"
163
     * Fields are separated by 0x0d "="
164
     * Ends with End Sentinel 0x0f "?"
165
     * Its 39 characters + the LRC
166
     * http://www.dataip.co.uk/Reference/MagneticCardBCD.php
167
     * 0x0a, 0x0c, 0x0e are some type of control
168
     * the FASCN has a lot of extra bits, with only 32 digits.
169
     */
170
0
    f5p = serialnr.value;
171
0
    f8p = guid_bin;
172
0
    fbyte = 0;
173
0
    fbyte2 = 0;
174
0
    fnibble = 0;
175
0
    fbits = 0;
176
0
    for (i = 0; i < 25*8; i++) {
177
0
      if (i%8 == 0) {
178
0
        fbyte=*f5p++;
179
0
      }
180
0
      fbit = (fbyte & 0x80) ? 1:0;
181
0
      fbyte <<= 1;
182
0
      fbits = (fbits >> 1) + (fbit << 4);
183
      /* reversed with parity */
184
0
      if ((i - 4)%5 == 0) {
185
0
        fbits = fbits & 0x0f; /* drop parity */
186
0
        if (fbits <= 9) {  /* only save digits, drop control codes */
187
0
          fbyte2 = (fbyte2 << 4) | fbits;
188
0
          if (fnibble) {
189
0
            *f8p = fbyte2;
190
0
            f8p++;
191
0
            fbyte2 = 0;
192
0
            fnibble = 0;
193
0
          } else
194
0
          fnibble = 1;
195
0
        }
196
0
        fbits = 0;
197
0
      }
198
0
    }
199
200
    /* overwrite two insignificant digits in middle with id */
201
0
    memcpy(guid_bin + 7, id.value, id.len);
202
0
    tlen = 16;
203
0
  }
204
0
  else if (id.len == 1 && serialnr.len == 16) {
205
    /* its from a GUID, we will overwrite the
206
     * first byte with id.value, as this preserves most
207
       * of the uniqueness.
208
     */
209
0
    memcpy(guid_bin, id.value, id.len);
210
0
    memcpy(guid_bin + id.len, serialnr.value + 1, serialnr.len - 1);
211
212
0
    tlen = id.len + serialnr.len - 1; /* i.e. 16 */
213
0
  } else {
214
    /* not what was expected...  use default */
215
216
0
    memcpy(guid_bin, serialnr.value, serialnr.len);
217
0
    memcpy(guid_bin + serialnr.len, id.value, id.len);
218
219
0
    tlen = id.len + serialnr.len;
220
0
  }
221
222
  /* reserve one byte for the 'C' line ending */
223
0
  bin_size = (*out_size - 1)/2;
224
0
  if (bin_size > tlen)
225
0
    bin_size = tlen;
226
227
0
  offs = tlen - bin_size;
228
229
0
  for (i=0; i<bin_size; i++)
230
0
    sprintf((char *) out + i*2, "%02x", guid_bin[offs + i]);
231
232
0
  return SC_SUCCESS;
233
0
}
234
235
236
static int piv_detect_card(sc_pkcs15_card_t *p15card)
237
0
{
238
0
  sc_card_t *card = p15card->card;
239
240
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
241
0
  if (card->type < SC_CARD_TYPE_PIV_II_BASE
242
0
    || card->type >= SC_CARD_TYPE_PIV_II_BASE + 1000)
243
0
    return SC_ERROR_INVALID_CARD;
244
0
  return SC_SUCCESS;
245
0
}
246
247
248
static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
249
0
{
250
251
  /* The cert objects will return all the data */
252
  /* Note: pkcs11 objects do not have CK_ID values */
253
254
  // clang-format off
255
0
  static const objdata objects[] = {
256
0
  {"01", "Card Capability Container",
257
0
      "2.16.840.1.101.3.7.1.219.0", NULL, "DB00", 0},
258
0
  {"02", "Card Holder Unique Identifier",
259
0
      "2.16.840.1.101.3.7.2.48.0", NULL, "3000", 0},
260
0
  {"03", "Unsigned Card Holder Unique Identifier",
261
0
      "2.16.840.1.101.3.7.2.48.2", NULL, "3010", 0},
262
0
  {"04", "X.509 Certificate for PIV Authentication",
263
0
      "2.16.840.1.101.3.7.2.1.1", NULL, "0101", 0},
264
0
  {"05", "Cardholder Fingerprints",
265
0
      "2.16.840.1.101.3.7.2.96.16", "01", "6010", SC_PKCS15_CO_FLAG_PRIVATE},
266
0
  {"06", "Printed Information",
267
0
      "2.16.840.1.101.3.7.2.48.1", "01", "3001", SC_PKCS15_CO_FLAG_PRIVATE},
268
0
  {"07", "Cardholder Facial Image",
269
0
      "2.16.840.1.101.3.7.2.96.48", "01", "6030", SC_PKCS15_CO_FLAG_PRIVATE},
270
0
  {"08", "X.509 Certificate for Digital Signature",
271
0
      "2.16.840.1.101.3.7.2.1.0",  NULL, "0100", 0},
272
0
  {"09", "X.509 Certificate for Key Management",
273
0
      "2.16.840.1.101.3.7.2.1.2", NULL, "0102", 0},
274
0
  {"10","X.509 Certificate for Card Authentication",
275
0
      "2.16.840.1.101.3.7.2.5.0", NULL, "0500", 0},
276
0
  {"11", "Security Object",
277
0
      "2.16.840.1.101.3.7.2.144.0", NULL, "9000", 0},
278
0
  {"12", "Discovery Object",
279
0
      "2.16.840.1.101.3.7.2.96.80", NULL, "6050", 0},
280
0
  {"13", "Key History Object",
281
0
      "2.16.840.1.101.3.7.2.96.96", NULL, "6060", 0},
282
0
  {"14", "Cardholder Iris Image",
283
0
      "2.16.840.1.101.3.7.2.16.21", NULL, "1015", SC_PKCS15_CO_FLAG_PRIVATE},
284
285
0
  {"15", "Retired X.509 Certificate for Key Management 1",
286
0
      "2.16.840.1.101.3.7.2.16.1", NULL, "1001", 0},
287
0
  {"16", "Retired X.509 Certificate for Key Management 2",
288
0
      "2.16.840.1.101.3.7.2.16.2", NULL, "1002", 0},
289
0
  {"17", "Retired X.509 Certificate for Key Management 3",
290
0
      "2.16.840.1.101.3.7.2.16.3", NULL, "1003", 0},
291
0
  {"18", "Retired X.509 Certificate for Key Management 4",
292
0
      "2.16.840.1.101.3.7.2.16.4", NULL, "1004", 0},
293
0
  {"19", "Retired X.509 Certificate for Key Management 5",
294
0
      "2.16.840.1.101.3.7.2.16.5", NULL, "1005", 0},
295
0
  {"20", "Retired X.509 Certificate for Key Management 6",
296
0
      "2.16.840.1.101.3.7.2.16.6", NULL, "1006", 0},
297
0
  {"21", "Retired X.509 Certificate for Key Management 7",
298
0
      "2.16.840.1.101.3.7.2.16.7", NULL, "1007", 0},
299
0
  {"22", "Retired X.509 Certificate for Key Management 8",
300
0
      "2.16.840.1.101.3.7.2.16.8", NULL, "1008", 0},
301
0
  {"23", "Retired X.509 Certificate for Key Management 9",
302
0
      "2.16.840.1.101.3.7.2.16.9", NULL, "1009", 0},
303
0
  {"24", "Retired X.509 Certificate for Key Management 10",
304
0
      "2.16.840.1.101.3.7.2.16.10", NULL, "100A", 0},
305
0
  {"25", "Retired X.509 Certificate for Key Management 11",
306
0
      "2.16.840.1.101.3.7.2.16.11", NULL, "100B", 0},
307
0
  {"26", "Retired X.509 Certificate for Key Management 12",
308
0
      "2.16.840.1.101.3.7.2.16.12", NULL, "100C", 0},
309
0
  {"27", "Retired X.509 Certificate for Key Management 13",
310
0
      "2.16.840.1.101.3.7.2.16.13", NULL, "100D", 0},
311
0
  {"28", "Retired X.509 Certificate for Key Management 14",
312
0
      "2.16.840.1.101.3.7.2.16.14", NULL, "100E", 0},
313
0
  {"29", "Retired X.509 Certificate for Key Management 15",
314
0
      "2.16.840.1.101.3.7.2.16.15", NULL, "100F", 0},
315
0
  {"30", "Retired X.509 Certificate for Key Management 16",
316
0
      "2.16.840.1.101.3.7.2.16.16", NULL, "1010", 0},
317
0
  {"31", "Retired X.509 Certificate for Key Management 17",
318
0
      "2.16.840.1.101.3.7.2.16.17", NULL, "1011", 0},
319
0
  {"32", "Retired X.509 Certificate for Key Management 18",
320
0
      "2.16.840.1.101.3.7.2.16.18", NULL, "1012", 0},
321
0
  {"33", "Retired X.509 Certificate for Key Management 19",
322
0
      "2.16.840.1.101.3.7.2.16.19", NULL, "1013", 0},
323
0
  {"34", "Retired X.509 Certificate for Key Management 20",
324
0
      "2.16.840.1.101.3.7.2.16.20", NULL, "1014", 0},
325
  /* new in 800-73-4 */
326
0
  {"35", "Biometric Information Templates Group Template",
327
0
      "2.16.840.1.101.3.7.2.16.22", NULL, "1016", 0},
328
0
  {"36", "Secure Messaging Certificate Signer",
329
0
      "2.16.840.1.101.3.7.2.16.23", NULL, "1017", 0},
330
0
  {"37", "Pairing Code Reference Data Container",
331
0
      "2.16.840.1.101.3.7.2.16.24", NULL, "1018", SC_PKCS15_CO_FLAG_PRIVATE},
332
0
  {NULL, NULL, NULL, NULL, NULL, 0}
333
0
  };
334
  // clang-format on
335
  /* NIST 800-73-1 lifted the restriction on
336
   * requiring pin protected certs. Thus the default is to
337
   * not require this.
338
   *
339
   * Certs will be pulled out from the cert objects
340
   * But there may be extra certs (SM Signer cert) that do
341
   * not have a private keys on the card. These certs must be last
342
   */
343
344
  /* Any certs on card without private key must be last */
345
0
#define PIV_NUM_CERTS 25
346
0
#define PIV_NUM_KEYS  24
347
348
  // clang-format off
349
0
  static const cdata certs[PIV_NUM_CERTS] = {
350
0
    {"01", "Certificate for PIV Authentication", "0101cece", 0, 0},
351
0
    {"02", "Certificate for Digital Signature", "0100cece", 0, 0},
352
0
    {"03", "Certificate for Key Management", "0102cece", 0, 0},
353
0
    {"04", "Certificate for Card Authentication", "0500cece", 0, 0},
354
0
    {"05", "Retired Certificate for Key Management 1", "1001cece", 0, 0},
355
0
    {"06", "Retired Certificate for Key Management 2", "1002cece", 0, 0},
356
0
    {"07", "Retired Certificate for Key Management 3", "1003cece", 0, 0},
357
0
    {"08", "Retired Certificate for Key Management 4", "1004cece", 0, 0},
358
0
    {"09", "Retired Certificate for Key Management 5", "1005cece", 0, 0},
359
0
    {"10", "Retired Certificate for Key Management 6", "1006cece", 0, 0},
360
0
    {"11", "Retired Certificate for Key Management 7", "1007cece", 0, 0},
361
0
    {"12", "Retired Certificate for Key Management 8", "1008cece", 0, 0},
362
0
    {"13", "Retired Certificate for Key Management 9", "1009cece", 0, 0},
363
0
    {"14", "Retired Certificate for Key Management 10", "100Acece", 0, 0},
364
0
    {"15", "Retired Certificate for Key Management 11", "100Bcece", 0, 0},
365
0
    {"16", "Retired Certificate for Key Management 12", "100Ccece", 0, 0},
366
0
    {"17", "Retired Certificate for Key Management 13", "100Dcece", 0, 0},
367
0
    {"18", "Retired Certificate for Key Management 14", "100Ecece", 0, 0},
368
0
    {"19", "Retired Certificate for Key Management 15", "100Fcece", 0, 0},
369
0
    {"20", "Retired Certificate for Key Management 16", "1010cece", 0, 0},
370
0
    {"21", "Retired Certificate for Key Management 17", "1011cece", 0, 0},
371
0
    {"22", "Retired Certificate for Key Management 18", "1012cece", 0, 0},
372
0
    {"23", "Retired Certificate for Key Management 19", "1013cece", 0, 0},
373
0
    {"24", "Retired Certificate for Key Management 20", "1014cece", 0, 0},
374
    /* Yubikey Attestation uses "25" but not read via GET_DATA */
375
0
    {"81", "Secure Messaging Certificate Signer",   "1017cece", 0, 0} /* no keys on card */
376
0
  };
377
  // clang-format on
378
379
  // clang-format off
380
0
  static const pindata pins[] = {
381
0
    { "01", "PIN", "", 0x80,
382
      /* label, flag  and ref will change if using global pin */
383
0
      SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
384
0
      8, 4, 8,
385
0
      SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
386
0
      SC_PKCS15_PIN_FLAG_INITIALIZED |
387
0
      SC_PKCS15_PIN_FLAG_LOCAL,
388
0
      -1, 0xFF,
389
0
      SC_PKCS15_CO_FLAG_PRIVATE, 0},
390
391
0
    { "02", "PIV PUK", "", 0x81,
392
0
      SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
393
0
      8, 4, 8,
394
0
      SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
395
0
      SC_PKCS15_PIN_FLAG_INITIALIZED |
396
0
      SC_PKCS15_PIN_FLAG_SO_PIN |
397
0
      SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN,
398
0
      -1, 0xFF,
399
0
      SC_PKCS15_CO_FLAG_PRIVATE, 0},
400
401
    /* only used with minidriver */
402
0
    { "03", "PIN", "", 0x80,
403
      /* used in minidriver as the sign key and for 9C key */
404
      /* label, flag  and ref will change if using global pin */
405
0
      SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
406
0
      8, 4, 8,
407
0
      SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
408
0
      SC_PKCS15_PIN_FLAG_INITIALIZED |
409
0
      SC_PKCS15_PIN_FLAG_LOCAL,
410
0
      -1, 0xFF,
411
0
      SC_PKCS15_CO_FLAG_PRIVATE, 1}, /* only use if cardmod */
412
0
    { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
413
0
  };
414
  // clang-format on
415
416
417
  /*
418
   * The size of the key or the algid is not really known
419
   * but can be derived from the certificates.
420
   * the cert, pubkey and privkey are a set.
421
   * Key usages bits taken from pkcs15v1_1 Table 2
422
   * RSA and EC have different sets of usage
423
   */
424
  // clang-format off
425
0
  static const pubdata pubkeys[PIV_NUM_KEYS] = {
426
0
    { "01", "PIV AUTH pubkey",
427
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
428
0
          SC_PKCS15_PRKEY_USAGE_WRAP |
429
0
          SC_PKCS15_PRKEY_USAGE_VERIFY |
430
0
          SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
431
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY,
432
0
      "9A06", 0x9A, NULL, 0, "PIV_9A_KEY"},
433
0
    { "02", "SIGN pubkey",
434
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
435
0
          SC_PKCS15_PRKEY_USAGE_VERIFY |
436
0
          SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER |
437
0
          SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
438
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY |
439
0
          SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
440
0
      "9C06", 0x9C, NULL, 0, "PIV_9C_KEY"},
441
0
    { "03", "KEY MAN pubkey",
442
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT| SC_PKCS15_PRKEY_USAGE_WRAP,
443
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
444
0
      "9D06", 0x9D, NULL, 0, "PIV_9D_KEY"},
445
0
    { "04", "CARD AUTH pubkey",
446
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_VERIFY |
447
0
          SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
448
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY,
449
0
      "9E06", 0x9E, NULL, 0, "PIV_9E_KEY"},  /* no pin, and avail in contactless */
450
451
0
    { "05", "Retired KEY MAN 1",
452
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
453
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
454
0
       "8206", 0x82, NULL, 0, NULL},
455
0
    { "06", "Retired KEY MAN 2",
456
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
457
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
458
0
       "8306", 0x83, NULL, 0, NULL},
459
0
    { "07", "Retired KEY MAN 3",
460
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
461
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
462
0
       "8406", 0x84, NULL, 0, NULL},
463
0
    { "08", "Retired KEY MAN 4",
464
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
465
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
466
0
       "8506", 0x85, NULL, 0, NULL},
467
0
    { "09", "Retired KEY MAN 5",
468
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
469
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
470
0
       "8606", 0x86, NULL, 0, NULL},
471
0
    { "10", "Retired KEY MAN 6",
472
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
473
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
474
0
       "8706", 0x87, NULL, 0, NULL},
475
0
    { "11", "Retired KEY MAN 7",
476
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
477
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
478
0
       "8806", 0x88, NULL, 0, NULL},
479
0
    { "12", "Retired KEY MAN 8",
480
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
481
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
482
0
       "8906", 0x89, NULL, 0, NULL},
483
0
    { "13", "Retired KEY MAN 9",
484
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
485
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
486
0
       "8A06", 0x8A, NULL, 0, NULL},
487
0
    { "14", "Retired KEY MAN 10",
488
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
489
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
490
0
       "8B06", 0x8B, NULL, 0, NULL},
491
0
    { "15", "Retired KEY MAN 11",
492
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
493
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
494
0
       "8C06", 0x8C, NULL, 0, NULL},
495
0
    { "16", "Retired KEY MAN 12",
496
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
497
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
498
0
       "8D06", 0x8D, NULL, 0, NULL},
499
0
    { "17", "Retired KEY MAN 13",
500
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
501
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
502
0
       "8E06", 0x8E, NULL, 0, NULL},
503
0
    { "18", "Retired KEY MAN 14",
504
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
505
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
506
0
       "8F06", 0x8F, NULL, 0, NULL},
507
0
    { "19", "Retired KEY MAN 15",
508
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
509
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
510
0
       "9006", 0x90, NULL, 0, NULL},
511
0
    { "20", "Retired KEY MAN 16",
512
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
513
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
514
0
       "9106", 0x91, NULL, 0, NULL},
515
0
    { "21", "Retired KEY MAN 17",
516
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
517
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
518
0
       "9206", 0x92, NULL, 0, NULL},
519
0
    { "22", "Retired KEY MAN 18",
520
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
521
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
522
0
       "9306", 0x93, NULL, 0, NULL},
523
0
    { "23", "Retired KEY MAN 19",
524
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
525
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
526
0
       "9406", 0x94, NULL, 0, NULL},
527
0
    { "24", "Retired KEY MAN 20",
528
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
529
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
530
0
       "9506", 0x95, NULL, 0, NULL}
531
0
  };
532
  // clang-format on
533
534
/*
535
 * Note some of the SC_PKCS15_PRKEY values are dependent
536
 * on the key algorithm, and will be reset.
537
538
 * No SM Signer private Key on card
539
 * The 04 SM ECC CVC pubkey is in response to SELECT AID
540
 */
541
  // clang-format off
542
0
  static const prdata prkeys[PIV_NUM_KEYS] = {
543
0
    { "01", "PIV AUTH key",
544
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT |
545
0
          SC_PKCS15_PRKEY_USAGE_UNWRAP |
546
0
          SC_PKCS15_PRKEY_USAGE_SIGN |
547
0
          SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
548
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_SIGN,
549
0
      "", 0x9A, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
550
0
    { "02", "SIGN key",
551
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT |
552
0
          SC_PKCS15_PRKEY_USAGE_SIGN |
553
0
          SC_PKCS15_PRKEY_USAGE_SIGNRECOVER |
554
0
          SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
555
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_SIGN |
556
0
          SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
557
0
      "", 0x9C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, /* use sign pin and user_consent */
558
0
    { "03", "KEY MAN key",
559
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
560
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
561
0
      "", 0x9D, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
562
0
    { "04", "CARD AUTH key",
563
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_SIGN |
564
0
        SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
565
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_SIGN,
566
0
      "", 0x9E, NULL, 0, 0}, /* no PIN needed, works with wireless */
567
0
    { "05", "Retired KEY MAN 1",
568
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
569
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
570
0
      "", 0x82, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
571
0
    { "06", "Retired KEY MAN 2",
572
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
573
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
574
0
      "", 0x83, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
575
0
    { "07", "Retired KEY MAN 3",
576
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
577
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
578
0
      "", 0x84, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
579
0
    { "08", "Retired KEY MAN 4",
580
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
581
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
582
0
      "", 0x85, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
583
0
    { "09", "Retired KEY MAN 5",
584
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
585
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
586
0
      "", 0x86, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
587
0
    { "10", "Retired KEY MAN 6",
588
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
589
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
590
0
      "", 0x87, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
591
0
    { "11", "Retired KEY MAN 7",
592
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
593
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
594
0
      "", 0x88, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
595
0
    { "12", "Retired KEY MAN 8",
596
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
597
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
598
0
      "", 0x89, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
599
0
    { "13", "Retired KEY MAN 9",
600
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
601
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
602
0
      "", 0x8A, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
603
0
    { "14", "Retired KEY MAN 10",
604
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
605
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
606
0
      "", 0x8B, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
607
0
    { "15", "Retired KEY MAN 11",
608
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
609
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
610
0
      "", 0x8C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
611
0
    { "16", "Retired KEY MAN 12",
612
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
613
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
614
0
      "", 0x8D, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
615
0
    { "17", "Retired KEY MAN 13",
616
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
617
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
618
0
      "", 0x8E, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
619
0
    { "18", "Retired KEY MAN 14",
620
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
621
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
622
0
      "", 0x8F, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
623
0
    { "19", "Retired KEY MAN 15",
624
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
625
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
626
0
      "", 0x90, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
627
0
    { "20", "Retired KEY MAN 16",
628
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
629
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
630
0
      "", 0x91, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
631
0
    { "21", "Retired KEY MAN 17",
632
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
633
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
634
0
      "", 0x92, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
635
0
    { "22", "Retired KEY MAN 18",
636
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
637
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
638
0
      "", 0x93, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
639
0
    { "23", "Retired KEY MAN 19",
640
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
641
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
642
0
      "", 0x94, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
643
0
    { "24", "Retired KEY MAN 20",
644
0
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
645
0
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
646
0
      "", 0x95, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}
647
    /* SM Signer certificate does not have private key on card */
648
0
  };
649
  // clang-format on
650
651
0
  int    r, i;
652
0
  sc_card_t *card = p15card->card;
653
0
  sc_serial_number_t serial;
654
0
  char buf[SC_MAX_SERIALNR * 2 + 1];
655
0
  common_key_info ckis[PIV_NUM_CERTS];
656
0
  int follows_nist_fascn = 0;
657
0
  char *token_name = NULL;
658
659
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
660
661
0
  memset(&serial, 0, sizeof(serial));
662
663
  /* could read this off card if needed */
664
665
  /* CSP does not like a - in the name */
666
0
  set_string(&p15card->tokeninfo->label, "PIV_II");
667
0
  set_string(&p15card->tokeninfo->manufacturer_id, MANU_ID);
668
669
  /*
670
   * get serial number
671
   * We will use the FASC-N from the CHUID
672
   * Note we are not verifying CHUID, belongs to this card
673
   * but need serial number for Mac tokend
674
   */
675
676
0
  r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
677
0
  if (r < 0) {
678
0
    sc_log(card->ctx, "sc_card_ctl rc=%d",r);
679
0
    set_string(&p15card->tokeninfo->serial_number, "00000000");
680
0
  } else {
681
0
    sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0);
682
0
    set_string(&p15card->tokeninfo->serial_number, buf);
683
0
  }
684
  /* US gov issued PIVs have CHUID with a FASCN that does not start with 9999 */
685
0
  if (serial.len == 25 && !(serial.value[0] == 0xD4 && serial.value[1] == 0xE7 && serial.value[2] == 0x39 && (serial.value[3] | 0x7F) == 0xFF)) {
686
0
      follows_nist_fascn = 1;
687
0
  }
688
689
0
  sc_log(card->ctx,  "PIV-II adding objects...");
690
691
  /* set other objects */
692
0
  for (i = 0; objects[i].label; i++) {
693
0
    struct sc_pkcs15_data_info obj_info;
694
0
    struct sc_pkcs15_object    obj_obj;
695
696
0
    memset(&obj_info, 0, sizeof(obj_info));
697
0
    memset(&obj_obj, 0, sizeof(obj_obj));
698
0
    sc_pkcs15_format_id(objects[i].id, &obj_info.id);
699
0
    sc_format_path(objects[i].path, &obj_info.path);
700
701
    /* See if the object can not be present on the card */
702
0
    r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &obj_info.path);
703
0
    if (r == 1)
704
0
      continue; /* Not on card, do not define the object */
705
706
0
    strncpy(obj_info.app_label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
707
0
    r = sc_format_oid(&obj_info.app_oid, objects[i].aoid);
708
0
    if (r != SC_SUCCESS)
709
0
      LOG_FUNC_RETURN(card->ctx, r);
710
711
    /* We can not read all the objects, as some need the PIN! */
712
0
    if (objects[i].auth_id)
713
0
      sc_pkcs15_format_id(objects[i].auth_id, &obj_obj.auth_id);
714
715
0
    strncpy(obj_obj.label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
716
0
    obj_obj.flags = objects[i].obj_flags;
717
718
0
    r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT,
719
0
      &obj_obj, &obj_info);
720
721
0
    if (r < 0)
722
0
      LOG_FUNC_RETURN(card->ctx, r);
723
0
  }
724
725
  /*
726
   * certs, pubkeys and priv keys are related and we assume
727
   * they are in order
728
   * We need to read the cert, get modulus and keylen
729
   * We use those for the pubkey, and priv key objects.
730
   * If no cert, then see if pubkey (i.e. we are initializing,
731
   * and the pubkey is in a file,) then add pubkey and privkey
732
   * If no cert and no pubkey, skip adding them.
733
734
   */
735
  /* set certs */
736
0
  sc_log(card->ctx,  "PIV-II adding certs...");
737
0
  for (i = 0; i < PIV_NUM_CERTS; i++) {
738
0
    struct sc_pkcs15_cert_info cert_info;
739
0
    struct sc_pkcs15_object    cert_obj;
740
0
    sc_pkcs15_der_t   cert_der;
741
0
    sc_pkcs15_cert_t *cert_out = NULL;
742
0
    int private_obj;
743
744
0
    ckis[i].cert_found = 0;
745
0
    ckis[i].key_alg = -1;
746
0
    ckis[i].pubkey_found = 0;
747
0
    ckis[i].pubkey_from_file = 0;
748
0
    ckis[i].pubkey_len = 0;
749
0
    ckis[i].pubkey_from_cert = NULL;
750
0
    ckis[i].cert_keyUsage = 0;
751
0
    ckis[i].cert_keyUsage_present = 0;
752
0
    ckis[i].pub_usage = 0;
753
0
    ckis[i].priv_usage = 0;
754
755
0
    memset(&cert_info, 0, sizeof(cert_info));
756
0
    memset(&cert_obj,  0, sizeof(cert_obj));
757
758
0
    sc_pkcs15_format_id(certs[i].id, &cert_info.id);
759
0
    cert_info.authority = certs[i].authority;
760
0
    sc_format_path(certs[i].path, &cert_info.path);
761
762
0
    strncpy(cert_obj.label, certs[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
763
0
    cert_obj.flags = certs[i].obj_flags;
764
765
    /* See if the cert might be present or not. */
766
0
    r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &cert_info.path);
767
0
    if (r == 1) {
768
0
      sc_log(card->ctx,  "Cert can not be present,i=%d", i);
769
0
      continue;
770
0
    }
771
772
0
    private_obj = cert_obj.flags & SC_PKCS15_CO_FLAG_PRIVATE;
773
0
    r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, private_obj);
774
775
0
    if (r) {
776
0
      sc_log(card->ctx,  "No cert found,i=%d", i);
777
0
      continue;
778
0
    }
779
780
0
    ckis[i].cert_found = 1;
781
    /* cache it using the PKCS15 emulation objects */
782
    /* as it does not change */
783
0
    if (cert_der.value) {
784
0
      cert_info.value.value = cert_der.value;
785
0
      cert_info.value.len = cert_der.len;
786
0
      if (!p15card->opts.use_file_cache
787
0
          || (private_obj && !(p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES))) {
788
0
        cert_info.path.len = 0; /* use in mem cert from now on */
789
0
      }
790
0
    }
791
    /* following will find the cached cert in cert_info */
792
0
    r =  sc_pkcs15_read_certificate(p15card, &cert_info, private_obj, &cert_out);
793
0
    if (r < 0 || cert_out == NULL || cert_out->key == NULL) {
794
0
      sc_log(card->ctx,  "Failed to read/parse the certificate r=%d",r);
795
0
      if (cert_out != NULL)
796
0
        sc_pkcs15_free_certificate(cert_out);
797
0
      free(cert_der.value);
798
0
      continue;
799
0
    }
800
801
    /* set the token name to the name of the CN of the first certificate */
802
0
    if (!token_name) {
803
0
      u8 * cn_name = NULL;
804
0
      size_t cn_len = 0;
805
0
      static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }};
806
0
      r = sc_pkcs15_get_name_from_dn(card->ctx, cert_out->subject,
807
0
        cert_out->subject_len, &cn_oid, &cn_name, &cn_len);
808
0
      if (r == SC_SUCCESS) {
809
0
        token_name = malloc (cn_len+1);
810
0
        if (!token_name) {
811
0
          sc_pkcs15_free_certificate(cert_out);
812
0
          free(cn_name);
813
0
          r = SC_ERROR_OUT_OF_MEMORY;
814
0
          LOG_TEST_GOTO_ERR(card->ctx, r,
815
0
            "Failed to allocate memory");
816
0
        }
817
0
        memcpy(token_name, cn_name, cn_len);
818
0
        free(cn_name);
819
0
        token_name[cn_len] = 0;
820
0
        free(p15card->tokeninfo->label);
821
0
        p15card->tokeninfo->label = token_name;
822
0
      }
823
0
    }
824
825
    /*
826
     * get keyUsage if present save in ckis[i]
827
     * Will only use it if this in a non FED issued card
828
     * which has a CHUID with FASC-N not starting with 9999
829
     */
830
831
0
    if (follows_nist_fascn == 0) {
832
0
      struct sc_object_id keyUsage_oid={{2,5,29,15,-1}};
833
0
      int r = 0;
834
835
0
      r = sc_pkcs15_get_bitstring_extension(card->ctx, cert_out,
836
0
        &keyUsage_oid,
837
0
        &ckis[i].cert_keyUsage, NULL);
838
0
      if ( r >= 0)
839
0
        ckis[i].cert_keyUsage_present = 1;
840
        /* TODO if no key usage, we could set all uses */
841
0
    }
842
843
844
0
    ckis[i].key_alg = cert_out->key->algorithm;
845
0
    switch (cert_out->key->algorithm) {
846
0
      case SC_ALGORITHM_RSA:
847
        /* save pubkey_len for pub and priv */
848
0
        ckis[i].pubkey_len = cert_out->key->u.rsa.modulus.len * 8;
849
        /* See RFC 5280 and PKCS#11 V2.40 */
850
0
        if (ckis[i].cert_keyUsage_present) {
851
0
          if (ckis[i].cert_keyUsage & SC_X509_DIGITAL_SIGNATURE) {
852
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT /* extra*/
853
0
                  |SC_PKCS15_PRKEY_USAGE_WRAP
854
0
                  |SC_PKCS15_PRKEY_USAGE_VERIFY
855
0
                  |SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER;
856
0
                  ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT /*extra */
857
0
                  |SC_PKCS15_PRKEY_USAGE_UNWRAP
858
0
                  |SC_PKCS15_PRKEY_USAGE_SIGN
859
0
                  |SC_PKCS15_PRKEY_USAGE_SIGNRECOVER;
860
0
          }
861
0
          if (ckis[i].cert_keyUsage & SC_X509_NON_REPUDIATION) {
862
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT /* extra */
863
0
                  |SC_PKCS15_PRKEY_USAGE_NONREPUDIATION
864
0
                  |SC_PKCS15_PRKEY_USAGE_VERIFY
865
0
                  |SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER;
866
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT /*extra*/
867
0
                  |SC_PKCS15_PRKEY_USAGE_NONREPUDIATION
868
0
                  |SC_PKCS15_PRKEY_USAGE_SIGN
869
0
                  |SC_PKCS15_PRKEY_USAGE_SIGNRECOVER;
870
0
          }
871
0
          if (ckis[i].cert_keyUsage & SC_X509_KEY_ENCIPHERMENT) {
872
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT| SC_PKCS15_PRKEY_USAGE_WRAP;
873
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT| SC_PKCS15_PRKEY_USAGE_UNWRAP;
874
0
          }
875
0
          if (ckis[i].cert_keyUsage & SC_X509_DATA_ENCIPHERMENT) {
876
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT;
877
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT;
878
0
          }
879
0
          if (ckis[i].cert_keyUsage & SC_X509_KEY_AGREEMENT) {
880
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
881
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
882
0
          }
883
0
          if (ckis[i].cert_keyUsage & SC_X509_KEY_CERT_SIGN) {
884
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_VERIFY|SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER;
885
0
            ckis[i].priv_usage |=  SC_PKCS15_PRKEY_USAGE_SIGN;
886
0
          }
887
0
          if (ckis[i].cert_keyUsage & SC_X509_CRL_SIGN) {
888
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_VERIFY|SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER;
889
0
            ckis[i].priv_usage |=  SC_PKCS15_PRKEY_USAGE_SIGN;
890
0
          }
891
0
          if (ckis[i].cert_keyUsage & SC_X509_ENCIPHER_ONLY) {
892
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT|SC_PKCS15_PRKEY_USAGE_WRAP;
893
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP;
894
0
          }
895
0
          if (ckis[i].cert_keyUsage & SC_X509_DECIPHER_ONLY) { /* TODO is this correct */
896
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP;
897
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT|SC_PKCS15_PRKEY_USAGE_WRAP;
898
0
          }
899
0
        }
900
0
        break;
901
902
0
      case SC_ALGORITHM_EC:
903
0
      case SC_ALGORITHM_EDDSA:
904
0
      case SC_ALGORITHM_XEDDSA:
905
0
        ckis[i].pubkey_len = cert_out->key->u.ec.params.field_length;
906
0
        if (ckis[i].cert_keyUsage_present) {
907
0
          if (ckis[i].cert_keyUsage & SC_X509_DIGITAL_SIGNATURE) {
908
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_VERIFY;
909
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_SIGN;
910
0
          }
911
0
          if (ckis[i].cert_keyUsage & SC_X509_NON_REPUDIATION) {
912
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
913
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
914
0
          }
915
0
          if (ckis[i].cert_keyUsage & SC_X509_KEY_ENCIPHERMENT) {
916
0
            ckis[i].pub_usage |= 0;
917
0
            ckis[i].priv_usage |= 0;
918
0
          }
919
0
          if (ckis[i].cert_keyUsage & SC_X509_DATA_ENCIPHERMENT) {
920
0
            ckis[i].pub_usage |= 0;
921
0
            ckis[i].priv_usage |= 0;
922
0
          }
923
0
          if (ckis[i].cert_keyUsage & SC_X509_KEY_AGREEMENT) {
924
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
925
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_DERIVE;
926
0
          }
927
0
          if (ckis[i].cert_keyUsage & SC_X509_KEY_CERT_SIGN) {
928
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_VERIFY;
929
0
            ckis[i].priv_usage |= SC_PKCS15_PRKEY_USAGE_SIGN;
930
0
          }
931
0
          if (ckis[i].cert_keyUsage & SC_X509_CRL_SIGN) {
932
0
            ckis[i].pub_usage |= SC_PKCS15_PRKEY_USAGE_VERIFY;
933
0
            ckis[i].priv_usage |=  SC_PKCS15_PRKEY_USAGE_SIGN;
934
0
          }
935
0
          if (ckis[i].cert_keyUsage & SC_X509_ENCIPHER_ONLY) {
936
0
            ckis[i].pub_usage |= 0;
937
0
            ckis[i].priv_usage |= 0;
938
0
          }
939
0
          if (ckis[i].cert_keyUsage & SC_X509_DECIPHER_ONLY) {
940
0
            ckis[i].pub_usage |= 0;
941
0
            ckis[i].priv_usage |= 0;
942
0
          }
943
0
        }
944
0
        break;
945
946
0
      default:
947
0
        sc_log(card->ctx, "Unsupported key.algorithm %lu", cert_out->key->algorithm);
948
0
        ckis[i].pubkey_len = 0; /* set some value for now */
949
0
    }
950
0
    if (i < PIV_NUM_KEYS) { /* Only save pub key if card can have private key */
951
0
      ckis[i].pubkey_from_cert = cert_out->key;
952
0
      cert_out->key = NULL;
953
0
    }
954
0
    sc_pkcs15_free_certificate(cert_out);
955
956
0
    r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
957
0
    if (r < 0) {
958
0
      sc_log(card->ctx,  " Failed to add cert obj r=%d",r);
959
0
      continue;
960
0
    }
961
0
  }
962
963
  /* set pins */
964
0
  sc_log(card->ctx,  "PIV-II adding pins...");
965
0
  for (i = 0; pins[i].label; i++) {
966
0
    struct sc_pkcs15_auth_info pin_info;
967
0
    struct sc_pkcs15_object   pin_obj;
968
0
    const char * label;
969
0
    int pin_ref;
970
971
    /* the SignPIN is only used with minidriver */
972
0
    if (pins[i].cardmod && (strcmp(card->ctx->app_name, "cardmod") != 0))
973
0
      continue;
974
975
0
    memset(&pin_info, 0, sizeof(pin_info));
976
0
    memset(&pin_obj,  0, sizeof(pin_obj));
977
978
0
    pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
979
0
    sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id);
980
0
    pin_info.attrs.pin.reference     = pins[i].ref;
981
0
    pin_info.attrs.pin.flags         = pins[i].flags;
982
0
    pin_info.attrs.pin.type          = pins[i].type;
983
0
    pin_info.attrs.pin.min_length    = pins[i].minlen;
984
0
    pin_info.attrs.pin.stored_length = pins[i].storedlen;
985
0
    pin_info.attrs.pin.max_length    = pins[i].maxlen;
986
0
    pin_info.attrs.pin.pad_char      = pins[i].pad_char;
987
0
    pin_info.tries_left              = pins[i].tries_left;
988
0
    sc_format_path(pins[i].path, &pin_info.path);
989
990
0
    label = pins[i].label;
991
0
    if ((i == 0 || pins[i].cardmod) &&
992
0
      sc_card_ctl(card, SC_CARDCTL_PIV_PIN_PREFERENCE,
993
0
          &pin_ref) == 0 &&
994
0
        pin_ref == 0x00) { /* must be 80 for PIV pin, or 00 for Global PIN */
995
0
      pin_info.attrs.pin.reference = pin_ref;
996
0
      label = "Global PIN";
997
0
    }
998
999
0
    strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1000
0
    pin_obj.flags = pins[i].obj_flags;
1001
0
    if ((i == 0 || pins[i].cardmod)) {
1002
      /*
1003
       * according to description of "RESET RETRY COUNTER"
1004
       * command in specs PUK can only unblock PIV PIN
1005
       */
1006
0
      pin_obj.auth_id.len = 1;
1007
0
      pin_obj.auth_id.value[0] = 2;
1008
0
    }
1009
1010
0
    r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
1011
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add PIN");
1012
0
  }
1013
1014
  /* set public keys */
1015
  /* We may only need this during initialization when genkey
1016
   * gets the pubkey, but it can not be read from the card
1017
   * at a later time. The piv-tool can stash  pubkey in file
1018
   */
1019
0
  sc_log(card->ctx,  "PIV-II adding pub keys...");
1020
0
  for (i = 0; i < PIV_NUM_KEYS; i++) {
1021
0
    struct sc_pkcs15_pubkey_info pubkey_info;
1022
0
    struct sc_pkcs15_object     pubkey_obj;
1023
0
    struct sc_pkcs15_pubkey *p15_key = NULL;
1024
1025
0
    memset(&pubkey_info, 0, sizeof(pubkey_info));
1026
0
    memset(&pubkey_obj,  0, sizeof(pubkey_obj));
1027
1028
1029
0
    sc_pkcs15_format_id(pubkeys[i].id, &pubkey_info.id);
1030
0
    pubkey_info.native        = 1;
1031
0
    pubkey_info.key_reference = pubkeys[i].ref;
1032
1033
//    sc_format_path(pubkeys[i].path, &pubkey_info.path);
1034
1035
0
    strncpy(pubkey_obj.label, pubkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1036
1037
0
    pubkey_obj.flags = pubkeys[i].obj_flags;
1038
1039
0
    if (pubkeys[i].auth_id)
1040
0
      sc_pkcs15_format_id(pubkeys[i].auth_id, &pubkey_obj.auth_id);
1041
1042
    /* If no cert found, piv-tool may have stashed the pubkey
1043
     * so we can use it when generating a certificate request
1044
     * The file is a OpenSSL DER EVP_KEY, which looks like
1045
     * a certificate subjectPublicKeyInfo.
1046
     *
1047
     */
1048
0
    if (ckis[i].cert_found == 0 ) { /*  no cert found */
1049
0
      char * filename = NULL;
1050
1051
0
      sc_log(card->ctx, "No cert for this pub key i=%d",i);
1052
1053
      /*
1054
       * If we used the piv-tool to generate a key,
1055
       * we would have saved the public key as a file.
1056
       * This code is only used while signing a request
1057
       * After the certificate is loaded on the card,
1058
       * the public key is extracted from the certificate.
1059
       */
1060
1061
1062
0
      sc_log(card->ctx, "DEE look for env %s",
1063
0
          pubkeys[i].getenvname?pubkeys[i].getenvname:"NULL");
1064
1065
0
      if (pubkeys[i].getenvname == NULL)
1066
0
        continue;
1067
1068
0
      filename = getenv(pubkeys[i].getenvname);
1069
0
      sc_log(card->ctx, "DEE look for file %s", filename?filename:"NULL");
1070
0
      if (filename == NULL)
1071
0
        continue;
1072
1073
0
      sc_log(card->ctx, "Adding pubkey from file %s",filename);
1074
1075
0
      r = sc_pkcs15_pubkey_from_spki_file(card->ctx,  filename, &p15_key);
1076
0
      if (r < 0) {
1077
0
        free(p15_key);
1078
0
        continue;
1079
0
      }
1080
1081
      /* Lets also try another method. */
1082
0
      r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, p15_key, &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len);
1083
0
      LOG_TEST_GOTO_ERR(card->ctx, r, "SPKI encode public key error");
1084
1085
      /* Only get here if no cert, and the the above found the
1086
       * pub key file (actually the SPKI version). This only
1087
       * happens when trying initializing a card and have set
1088
       * env PIV_9A_KEY or 9C, 9D, 9E to point at the file.
1089
       *
1090
       * We will cache it using the PKCS15 emulation objects
1091
       */
1092
1093
0
      pubkey_info.path.len = 0;
1094
1095
0
      ckis[i].key_alg = p15_key->algorithm;
1096
0
      switch (p15_key->algorithm) {
1097
0
        case SC_ALGORITHM_RSA:
1098
          /* save pubkey_len in pub and priv */
1099
0
          ckis[i].pubkey_len = p15_key->u.rsa.modulus.len * 8;
1100
0
          ckis[i].pubkey_found = 1;
1101
0
          ckis[i].pubkey_from_file = 1;
1102
0
          break;
1103
0
        case SC_ALGORITHM_EC:
1104
0
        case SC_ALGORITHM_EDDSA:
1105
0
        case SC_ALGORITHM_XEDDSA:
1106
0
          ckis[i].key_alg = p15_key->algorithm;
1107
0
          ckis[i].pubkey_len = p15_key->u.ec.params.field_length;
1108
0
          ckis[i].pubkey_found = 1;
1109
0
          ckis[i].pubkey_from_file = 1;
1110
0
          break;
1111
0
        default:
1112
0
          sc_log(card->ctx, "Unsupported key_alg %lu", p15_key->algorithm);
1113
0
          continue;
1114
0
      }
1115
0
      pubkey_obj.emulated = p15_key;
1116
0
      p15_key = NULL;
1117
0
    }
1118
0
    else if (ckis[i].pubkey_from_cert)   {
1119
0
      r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, ckis[i].pubkey_from_cert,
1120
0
        &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len);
1121
0
      LOG_TEST_GOTO_ERR(card->ctx, r, "SPKI encode public key error");
1122
1123
0
      pubkey_obj.emulated = ckis[i].pubkey_from_cert;
1124
0
      ckis[i].pubkey_from_cert = NULL;
1125
0
    }
1126
1127
0
    sc_log(card->ctx, "adding pubkey for %d keyalg=%lu", i, ckis[i].key_alg);
1128
0
    switch (ckis[i].key_alg) {
1129
0
      case SC_ALGORITHM_RSA:
1130
0
        if (ckis[i].cert_keyUsage_present) {
1131
0
          pubkey_info.usage =  ckis[i].pub_usage;
1132
0
        } else {
1133
0
          pubkey_info.usage = pubkeys[i].usage_rsa;
1134
0
        }
1135
0
        pubkey_info.modulus_length = ckis[i].pubkey_len;
1136
0
        strncpy(pubkey_obj.label, pubkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1137
1138
        /* should not fail */
1139
0
        r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
1140
0
        LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add RSA pubkey");
1141
1142
0
        ckis[i].pubkey_found = 1;
1143
0
        break;
1144
0
      case SC_ALGORITHM_EC:
1145
0
      case SC_ALGORITHM_EDDSA:
1146
0
      case SC_ALGORITHM_XEDDSA:
1147
0
        if (ckis[i].cert_keyUsage_present) {
1148
0
          pubkey_info.usage = ckis[i].pub_usage;
1149
0
        } else {
1150
0
          pubkey_info.usage = pubkeys[i].usage_ec;
1151
0
        }
1152
1153
0
        pubkey_info.field_length = ckis[i].pubkey_len;
1154
0
        strncpy(pubkey_obj.label, pubkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1155
1156
        /* should not fail */
1157
1158
0
        if (ckis[i].key_alg == SC_ALGORITHM_EDDSA)
1159
0
          r = sc_pkcs15emu_add_eddsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
1160
0
        else if (ckis[i].key_alg == SC_ALGORITHM_XEDDSA)
1161
0
          r = sc_pkcs15emu_add_xeddsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
1162
0
        else
1163
0
          r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
1164
1165
0
        LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add EC pubkey");
1166
1167
0
        ckis[i].pubkey_found = 1;
1168
0
        break;
1169
0
      default:
1170
0
        sc_log(card->ctx, "key_alg %lu not supported", ckis[i].key_alg);
1171
0
        continue;
1172
0
    }
1173
0
    sc_log(card->ctx, "USAGE: cert_keyUsage_present:%d usage:0x%8.8x",
1174
0
        ckis[i].cert_keyUsage_present, pubkey_info.usage);
1175
0
  }
1176
1177
1178
  /* set private keys */
1179
0
  sc_log(card->ctx,  "PIV-II adding private keys...");
1180
0
  for (i = 0; i < PIV_NUM_KEYS; i++) {
1181
0
    struct sc_pkcs15_prkey_info prkey_info;
1182
0
    struct sc_pkcs15_object     prkey_obj;
1183
1184
0
    memset(&prkey_info, 0, sizeof(prkey_info));
1185
0
    memset(&prkey_obj,  0, sizeof(prkey_obj));
1186
1187
0
    if (ckis[i].cert_found == 0 && ckis[i].pubkey_found == 0)
1188
0
      continue; /* i.e. no cert or pubkey */
1189
1190
0
    sc_pkcs15_format_id(prkeys[i].id, &prkey_info.id);
1191
0
    prkey_info.native        = 1;
1192
0
    prkey_info.key_reference = prkeys[i].ref;
1193
0
    sc_format_path(prkeys[i].path, &prkey_info.path);
1194
1195
0
    strncpy(prkey_obj.label, prkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1196
0
    prkey_obj.flags = prkeys[i].obj_flags;
1197
0
    prkey_obj.user_consent = prkeys[i].user_consent; /* only Sign key */
1198
1199
0
    if (prkeys[i].auth_id)
1200
0
      sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id);
1201
1202
    /* If using minidriver, use Sign PIN  for 9C key */
1203
0
    if (prkey_obj.user_consent && (strcmp(card->ctx->app_name, "cardmod") == 0))
1204
0
      sc_pkcs15_format_id("03", &prkey_obj.auth_id);
1205
1206
    /*
1207
     * When no cert is present and a pubkey in a file was found,
1208
     * means the caller is initializing a card. A sign operation
1209
     * will be required to sign a certificate request even if
1210
     * normal usage would not allow it. Set SC_PKCS15_PRKEY_USAGE_SIGN
1211
     * TODO if code is added to allow key generation and request
1212
     * sign in the same session, similar code will be needed.
1213
     */
1214
1215
0
    if (ckis[i].pubkey_from_file == 1) {
1216
0
      prkey_info.usage = SC_PKCS15_PRKEY_USAGE_SIGN;
1217
0
      sc_log(card->ctx,  "Adding SC_PKCS15_PRKEY_USAGE_SIGN");
1218
0
    }
1219
1220
0
    switch (ckis[i].key_alg) {
1221
0
      case SC_ALGORITHM_RSA:
1222
0
        if(ckis[i].cert_keyUsage_present) {
1223
0
          prkey_info.usage |= ckis[i].priv_usage;
1224
          /* If retired key and non gov cert has NONREPUDIATION, treat as user_consent */
1225
0
          if (i >= 4 && (ckis[i].priv_usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)) {
1226
0
            prkey_obj.user_consent = 1;
1227
0
          }
1228
0
        } else {
1229
0
          prkey_info.usage |= prkeys[i].usage_rsa;
1230
0
        }
1231
0
        prkey_info.modulus_length= ckis[i].pubkey_len;
1232
0
        r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
1233
0
        break;
1234
0
      case SC_ALGORITHM_EC:
1235
0
      case SC_ALGORITHM_EDDSA:
1236
0
      case SC_ALGORITHM_XEDDSA:
1237
0
        if (ckis[i].cert_keyUsage_present) {
1238
0
          prkey_info.usage  |= ckis[i].priv_usage;
1239
          /* If retired key and non gov cert has NONREPUDIATION, treat as user_consent */
1240
0
          if (i >= 4 && (ckis[i].priv_usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)) {
1241
0
            prkey_obj.user_consent = 1;
1242
0
          }
1243
0
        } else {
1244
0
          prkey_info.usage  |= prkeys[i].usage_ec;
1245
0
        }
1246
0
        prkey_info.field_length = ckis[i].pubkey_len;
1247
0
        sc_log(card->ctx, "DEE added key_alg %2.2lx prkey_obj.flags %8.8x",
1248
0
           ckis[i].key_alg, prkey_obj.flags);
1249
1250
0
        if (ckis[i].key_alg == SC_ALGORITHM_EDDSA)
1251
0
          r = sc_pkcs15emu_add_eddsa_prkey(p15card, &prkey_obj, &prkey_info);
1252
0
        else if (ckis[i].key_alg == SC_ALGORITHM_XEDDSA)
1253
0
          r = sc_pkcs15emu_add_xeddsa_prkey(p15card, &prkey_obj, &prkey_info);
1254
0
        else
1255
0
          r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info);
1256
0
        break;
1257
0
      default:
1258
0
        sc_log(card->ctx, "Unsupported key_alg %lu", ckis[i].key_alg);
1259
0
        r = 0; /* we just skip this one */
1260
0
    }
1261
0
    sc_log(card->ctx, "USAGE: cert_keyUsage_present:%d usage:0x%8.8x", ckis[i].cert_keyUsage_present, prkey_info.usage);
1262
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add Private key");
1263
0
  }
1264
1265
0
  p15card->ops.get_guid = piv_get_guid;
1266
1267
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1268
0
err:
1269
0
  for (i = 0; i < PIV_NUM_CERTS; i++) {
1270
0
    sc_pkcs15_free_pubkey(ckis[i].pubkey_from_cert);
1271
0
  }
1272
0
  sc_pkcs15_card_clear(p15card);
1273
0
  LOG_FUNC_RETURN(card->ctx, r);
1274
0
}
1275
1276
int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card,
1277
    struct sc_aid *aid)
1278
0
{
1279
0
  sc_card_t   *card = p15card->card;
1280
0
  sc_context_t    *ctx = card->ctx;
1281
1282
0
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
1283
1284
0
  if (piv_detect_card(p15card))
1285
0
    return SC_ERROR_WRONG_CARD;
1286
0
  return sc_pkcs15emu_piv_init(p15card);
1287
0
}