Coverage Report

Created: 2026-07-10 06:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/pkcs15-piv.c
Line
Count
Source
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-2026 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
601
#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
10.4k
{
238
10.4k
  sc_card_t *card = p15card->card;
239
240
10.4k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
241
10.4k
  if (card->type < SC_CARD_TYPE_PIV_II_BASE
242
6.29k
    || card->type >= SC_CARD_TYPE_PIV_II_BASE + 1000)
243
9.85k
    return SC_ERROR_INVALID_CARD;
244
601
  return SC_SUCCESS;
245
10.4k
}
246
247
248
static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
249
601
{
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
601
  static const objdata objects[] = {
256
601
  {"01", "Card Capability Container",
257
601
      "2.16.840.1.101.3.7.1.219.0", NULL, "DB00", 0},
258
601
  {"02", "Card Holder Unique Identifier",
259
601
      "2.16.840.1.101.3.7.2.48.0", NULL, "3000", 0},
260
601
  {"03", "Unsigned Card Holder Unique Identifier",
261
601
      "2.16.840.1.101.3.7.2.48.2", NULL, "3010", 0},
262
601
  {"04", "X.509 Certificate for PIV Authentication",
263
601
      "2.16.840.1.101.3.7.2.1.1", NULL, "0101", 0},
264
601
  {"05", "Cardholder Fingerprints",
265
601
      "2.16.840.1.101.3.7.2.96.16", "01", "6010", SC_PKCS15_CO_FLAG_PRIVATE},
266
601
  {"06", "Printed Information",
267
601
      "2.16.840.1.101.3.7.2.48.1", "01", "3001", SC_PKCS15_CO_FLAG_PRIVATE},
268
601
  {"07", "Cardholder Facial Image",
269
601
      "2.16.840.1.101.3.7.2.96.48", "01", "6030", SC_PKCS15_CO_FLAG_PRIVATE},
270
601
  {"08", "X.509 Certificate for Digital Signature",
271
601
      "2.16.840.1.101.3.7.2.1.0",  NULL, "0100", 0},
272
601
  {"09", "X.509 Certificate for Key Management",
273
601
      "2.16.840.1.101.3.7.2.1.2", NULL, "0102", 0},
274
601
  {"10","X.509 Certificate for Card Authentication",
275
601
      "2.16.840.1.101.3.7.2.5.0", NULL, "0500", 0},
276
601
  {"11", "Security Object",
277
601
      "2.16.840.1.101.3.7.2.144.0", NULL, "9000", 0},
278
601
  {"12", "Discovery Object",
279
601
      "2.16.840.1.101.3.7.2.96.80", NULL, "6050", 0},
280
601
  {"13", "Key History Object",
281
601
      "2.16.840.1.101.3.7.2.96.96", NULL, "6060", 0},
282
601
  {"14", "Cardholder Iris Image",
283
601
      "2.16.840.1.101.3.7.2.16.21", NULL, "1015", SC_PKCS15_CO_FLAG_PRIVATE},
284
285
601
  {"15", "Retired X.509 Certificate for Key Management 1",
286
601
      "2.16.840.1.101.3.7.2.16.1", NULL, "1001", 0},
287
601
  {"16", "Retired X.509 Certificate for Key Management 2",
288
601
      "2.16.840.1.101.3.7.2.16.2", NULL, "1002", 0},
289
601
  {"17", "Retired X.509 Certificate for Key Management 3",
290
601
      "2.16.840.1.101.3.7.2.16.3", NULL, "1003", 0},
291
601
  {"18", "Retired X.509 Certificate for Key Management 4",
292
601
      "2.16.840.1.101.3.7.2.16.4", NULL, "1004", 0},
293
601
  {"19", "Retired X.509 Certificate for Key Management 5",
294
601
      "2.16.840.1.101.3.7.2.16.5", NULL, "1005", 0},
295
601
  {"20", "Retired X.509 Certificate for Key Management 6",
296
601
      "2.16.840.1.101.3.7.2.16.6", NULL, "1006", 0},
297
601
  {"21", "Retired X.509 Certificate for Key Management 7",
298
601
      "2.16.840.1.101.3.7.2.16.7", NULL, "1007", 0},
299
601
  {"22", "Retired X.509 Certificate for Key Management 8",
300
601
      "2.16.840.1.101.3.7.2.16.8", NULL, "1008", 0},
301
601
  {"23", "Retired X.509 Certificate for Key Management 9",
302
601
      "2.16.840.1.101.3.7.2.16.9", NULL, "1009", 0},
303
601
  {"24", "Retired X.509 Certificate for Key Management 10",
304
601
      "2.16.840.1.101.3.7.2.16.10", NULL, "100A", 0},
305
601
  {"25", "Retired X.509 Certificate for Key Management 11",
306
601
      "2.16.840.1.101.3.7.2.16.11", NULL, "100B", 0},
307
601
  {"26", "Retired X.509 Certificate for Key Management 12",
308
601
      "2.16.840.1.101.3.7.2.16.12", NULL, "100C", 0},
309
601
  {"27", "Retired X.509 Certificate for Key Management 13",
310
601
      "2.16.840.1.101.3.7.2.16.13", NULL, "100D", 0},
311
601
  {"28", "Retired X.509 Certificate for Key Management 14",
312
601
      "2.16.840.1.101.3.7.2.16.14", NULL, "100E", 0},
313
601
  {"29", "Retired X.509 Certificate for Key Management 15",
314
601
      "2.16.840.1.101.3.7.2.16.15", NULL, "100F", 0},
315
601
  {"30", "Retired X.509 Certificate for Key Management 16",
316
601
      "2.16.840.1.101.3.7.2.16.16", NULL, "1010", 0},
317
601
  {"31", "Retired X.509 Certificate for Key Management 17",
318
601
      "2.16.840.1.101.3.7.2.16.17", NULL, "1011", 0},
319
601
  {"32", "Retired X.509 Certificate for Key Management 18",
320
601
      "2.16.840.1.101.3.7.2.16.18", NULL, "1012", 0},
321
601
  {"33", "Retired X.509 Certificate for Key Management 19",
322
601
      "2.16.840.1.101.3.7.2.16.19", NULL, "1013", 0},
323
601
  {"34", "Retired X.509 Certificate for Key Management 20",
324
601
      "2.16.840.1.101.3.7.2.16.20", NULL, "1014", 0},
325
  /* new in 800-73-4 */
326
601
  {"35", "Biometric Information Templates Group Template",
327
601
      "2.16.840.1.101.3.7.2.16.22", NULL, "1016", 0},
328
601
  {"36", "Secure Messaging Certificate Signer",
329
601
      "2.16.840.1.101.3.7.2.16.23", NULL, "1017", 0},
330
601
  {"37", "Pairing Code Reference Data Container",
331
601
      "2.16.840.1.101.3.7.2.16.24", NULL, "1018", SC_PKCS15_CO_FLAG_PRIVATE},
332
601
  {NULL, NULL, NULL, NULL, NULL, 0}
333
601
  };
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
15.8k
#define PIV_NUM_CERTS 25
346
29.6k
#define PIV_NUM_KEYS  24
347
348
  // clang-format off
349
601
  static const cdata certs[PIV_NUM_CERTS] = {
350
601
    {"01", "Certificate for PIV Authentication", "0101cece", 0, 0},
351
601
    {"02", "Certificate for Digital Signature", "0100cece", 0, 0},
352
601
    {"03", "Certificate for Key Management", "0102cece", 0, 0},
353
601
    {"04", "Certificate for Card Authentication", "0500cece", 0, 0},
354
601
    {"05", "Retired Certificate for Key Management 1", "1001cece", 0, 0},
355
601
    {"06", "Retired Certificate for Key Management 2", "1002cece", 0, 0},
356
601
    {"07", "Retired Certificate for Key Management 3", "1003cece", 0, 0},
357
601
    {"08", "Retired Certificate for Key Management 4", "1004cece", 0, 0},
358
601
    {"09", "Retired Certificate for Key Management 5", "1005cece", 0, 0},
359
601
    {"10", "Retired Certificate for Key Management 6", "1006cece", 0, 0},
360
601
    {"11", "Retired Certificate for Key Management 7", "1007cece", 0, 0},
361
601
    {"12", "Retired Certificate for Key Management 8", "1008cece", 0, 0},
362
601
    {"13", "Retired Certificate for Key Management 9", "1009cece", 0, 0},
363
601
    {"14", "Retired Certificate for Key Management 10", "100Acece", 0, 0},
364
601
    {"15", "Retired Certificate for Key Management 11", "100Bcece", 0, 0},
365
601
    {"16", "Retired Certificate for Key Management 12", "100Ccece", 0, 0},
366
601
    {"17", "Retired Certificate for Key Management 13", "100Dcece", 0, 0},
367
601
    {"18", "Retired Certificate for Key Management 14", "100Ecece", 0, 0},
368
601
    {"19", "Retired Certificate for Key Management 15", "100Fcece", 0, 0},
369
601
    {"20", "Retired Certificate for Key Management 16", "1010cece", 0, 0},
370
601
    {"21", "Retired Certificate for Key Management 17", "1011cece", 0, 0},
371
601
    {"22", "Retired Certificate for Key Management 18", "1012cece", 0, 0},
372
601
    {"23", "Retired Certificate for Key Management 19", "1013cece", 0, 0},
373
601
    {"24", "Retired Certificate for Key Management 20", "1014cece", 0, 0},
374
    /* Yubikey Attestation uses "25" but not read via GET_DATA */
375
601
    {"81", "Secure Messaging Certificate Signer",   "1017cece", 0, 0} /* no keys on card */
376
601
  };
377
  // clang-format on
378
379
  // clang-format off
380
601
  static const pindata pins[] = {
381
601
    { "01", "PIN", "", 0x80,
382
      /* label, flag  and ref will change if using global pin */
383
601
      SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
384
601
      8, 4, 8,
385
601
      SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
386
601
      SC_PKCS15_PIN_FLAG_INITIALIZED |
387
601
      SC_PKCS15_PIN_FLAG_LOCAL,
388
601
      -1, 0xFF,
389
601
      SC_PKCS15_CO_FLAG_PRIVATE, 0},
390
391
601
    { "02", "PIV PUK", "", 0x81,
392
601
      SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
393
601
      8, 4, 8,
394
601
      SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
395
601
      SC_PKCS15_PIN_FLAG_INITIALIZED |
396
601
      SC_PKCS15_PIN_FLAG_SO_PIN |
397
601
      SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN,
398
601
      -1, 0xFF,
399
601
      SC_PKCS15_CO_FLAG_PRIVATE, 0},
400
401
    /* only used with minidriver */
402
601
    { "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
601
      SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
406
601
      8, 4, 8,
407
601
      SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
408
601
      SC_PKCS15_PIN_FLAG_INITIALIZED |
409
601
      SC_PKCS15_PIN_FLAG_LOCAL,
410
601
      -1, 0xFF,
411
601
      SC_PKCS15_CO_FLAG_PRIVATE, 1}, /* only use if cardmod */
412
601
    { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
413
601
  };
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
601
  static const pubdata pubkeys[PIV_NUM_KEYS] = {
426
601
    { "01", "PIV AUTH pubkey",
427
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
428
601
          SC_PKCS15_PRKEY_USAGE_WRAP |
429
601
          SC_PKCS15_PRKEY_USAGE_VERIFY |
430
601
          SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
431
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY,
432
601
      "9A06", 0x9A, NULL, 0, "PIV_9A_KEY"},
433
601
    { "02", "SIGN pubkey",
434
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
435
601
          SC_PKCS15_PRKEY_USAGE_VERIFY |
436
601
          SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER |
437
601
          SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
438
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY |
439
601
          SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
440
601
      "9C06", 0x9C, NULL, 0, "PIV_9C_KEY"},
441
601
    { "03", "KEY MAN pubkey",
442
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT| SC_PKCS15_PRKEY_USAGE_WRAP,
443
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
444
601
      "9D06", 0x9D, NULL, 0, "PIV_9D_KEY"},
445
601
    { "04", "CARD AUTH pubkey",
446
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_VERIFY |
447
601
          SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
448
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY,
449
601
      "9E06", 0x9E, NULL, 0, "PIV_9E_KEY"},  /* no pin, and avail in contactless */
450
451
601
    { "05", "Retired KEY MAN 1",
452
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
453
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
454
601
       "8206", 0x82, NULL, 0, "PIV_82_KEY"},
455
601
    { "06", "Retired KEY MAN 2",
456
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
457
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
458
601
       "8306", 0x83, NULL, 0, "PIV_83_KEY"},
459
601
    { "07", "Retired KEY MAN 3",
460
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
461
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
462
601
       "8406", 0x84, NULL, 0, "PIV_84_KEY"},
463
601
    { "08", "Retired KEY MAN 4",
464
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
465
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
466
601
       "8506", 0x85, NULL, 0, "PIV_85_KEY"},
467
601
    { "09", "Retired KEY MAN 5",
468
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
469
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
470
601
       "8606", 0x86, NULL, 0, "PIV_86_KEY"},
471
601
    { "10", "Retired KEY MAN 6",
472
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
473
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
474
601
       "8706", 0x87, NULL, 0, "PIV_87_KEY"},
475
601
    { "11", "Retired KEY MAN 7",
476
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
477
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
478
601
       "8806", 0x88, NULL, 0, "PIV_88_KEY"},
479
601
    { "12", "Retired KEY MAN 8",
480
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
481
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
482
601
       "8906", 0x89, NULL, 0, "PIV_89_KEY"},
483
601
    { "13", "Retired KEY MAN 9",
484
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
485
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
486
601
       "8A06", 0x8A, NULL, 0, "PIV_8A_KEY"},
487
601
    { "14", "Retired KEY MAN 10",
488
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
489
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
490
601
       "8B06", 0x8B, NULL, 0, "PIV_8B_KEY"},
491
601
    { "15", "Retired KEY MAN 11",
492
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
493
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
494
601
       "8C06", 0x8C, NULL, 0, "PIV_8C_KEY"},
495
601
    { "16", "Retired KEY MAN 12",
496
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
497
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
498
601
       "8D06", 0x8D, NULL, 0, "PIV_8D_KEY"},
499
601
    { "17", "Retired KEY MAN 13",
500
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
501
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
502
601
       "8E06", 0x8E, NULL, 0, "PIV_8E_KEY"},
503
601
    { "18", "Retired KEY MAN 14",
504
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
505
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
506
601
       "8F06", 0x8F, NULL, 0, "PIV_8F_KEY"},
507
601
    { "19", "Retired KEY MAN 15",
508
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
509
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
510
601
       "9006", 0x90, NULL, 0, "PIV_90_KEY"},
511
601
    { "20", "Retired KEY MAN 16",
512
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
513
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
514
601
       "9106", 0x91, NULL, 0, "PIV_91_KEY"},
515
601
    { "21", "Retired KEY MAN 17",
516
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
517
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
518
601
       "9206", 0x92, NULL, 0, "PIV_92_KEY"},
519
601
    { "22", "Retired KEY MAN 18",
520
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
521
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
522
601
       "9306", 0x93, NULL, 0, "PIV_93_KEY"},
523
601
    { "23", "Retired KEY MAN 19",
524
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
525
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
526
601
       "9406", 0x94, NULL, 0, "PIV_94_KEY"},
527
601
    { "24", "Retired KEY MAN 20",
528
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
529
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
530
601
       "9506", 0x95, NULL, 0, "PIV_95_KEY"}
531
601
  };
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
601
  static const prdata prkeys[PIV_NUM_KEYS] = {
543
601
    { "01", "PIV AUTH key",
544
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT |
545
601
          SC_PKCS15_PRKEY_USAGE_UNWRAP |
546
601
          SC_PKCS15_PRKEY_USAGE_SIGN |
547
601
          SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
548
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_SIGN,
549
601
      "", 0x9A, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
550
601
    { "02", "SIGN key",
551
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT |
552
601
          SC_PKCS15_PRKEY_USAGE_SIGN |
553
601
          SC_PKCS15_PRKEY_USAGE_SIGNRECOVER |
554
601
          SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
555
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_SIGN |
556
601
          SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
557
601
      "", 0x9C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}, /* use sign pin and user_consent */
558
601
    { "03", "KEY MAN key",
559
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
560
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
561
601
      "", 0x9D, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
562
601
    { "04", "CARD AUTH key",
563
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_SIGN |
564
601
        SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
565
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_SIGN,
566
601
      "", 0x9E, NULL, 0, 0}, /* no PIN needed, works with wireless */
567
601
    { "05", "Retired KEY MAN 1",
568
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
569
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
570
601
      "", 0x82, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
571
601
    { "06", "Retired KEY MAN 2",
572
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
573
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
574
601
      "", 0x83, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
575
601
    { "07", "Retired KEY MAN 3",
576
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
577
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
578
601
      "", 0x84, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
579
601
    { "08", "Retired KEY MAN 4",
580
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
581
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
582
601
      "", 0x85, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
583
601
    { "09", "Retired KEY MAN 5",
584
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
585
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
586
601
      "", 0x86, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
587
601
    { "10", "Retired KEY MAN 6",
588
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
589
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
590
601
      "", 0x87, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
591
601
    { "11", "Retired KEY MAN 7",
592
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
593
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
594
601
      "", 0x88, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
595
601
    { "12", "Retired KEY MAN 8",
596
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
597
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
598
601
      "", 0x89, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
599
601
    { "13", "Retired KEY MAN 9",
600
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
601
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
602
601
      "", 0x8A, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
603
601
    { "14", "Retired KEY MAN 10",
604
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
605
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
606
601
      "", 0x8B, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
607
601
    { "15", "Retired KEY MAN 11",
608
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
609
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
610
601
      "", 0x8C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
611
601
    { "16", "Retired KEY MAN 12",
612
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
613
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
614
601
      "", 0x8D, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
615
601
    { "17", "Retired KEY MAN 13",
616
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
617
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
618
601
      "", 0x8E, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
619
601
    { "18", "Retired KEY MAN 14",
620
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
621
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
622
601
      "", 0x8F, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
623
601
    { "19", "Retired KEY MAN 15",
624
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
625
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
626
601
      "", 0x90, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
627
601
    { "20", "Retired KEY MAN 16",
628
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
629
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
630
601
      "", 0x91, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
631
601
    { "21", "Retired KEY MAN 17",
632
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
633
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
634
601
      "", 0x92, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
635
601
    { "22", "Retired KEY MAN 18",
636
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
637
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
638
601
      "", 0x93, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
639
601
    { "23", "Retired KEY MAN 19",
640
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
641
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
642
601
      "", 0x94, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
643
601
    { "24", "Retired KEY MAN 20",
644
601
        /*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
645
601
        /*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
646
601
      "", 0x95, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0}
647
    /* SM Signer certificate does not have private key on card */
648
601
  };
649
  // clang-format on
650
651
601
  int    r, i;
652
601
  sc_card_t *card = p15card->card;
653
601
  sc_serial_number_t serial;
654
601
  char buf[SC_MAX_SERIALNR * 2 + 1];
655
601
  common_key_info ckis[PIV_NUM_CERTS];
656
601
  int follows_nist_fascn = 0;
657
601
  char *token_name = NULL;
658
659
601
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
660
661
601
  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
601
  set_string(&p15card->tokeninfo->label, "PIV_II");
667
601
  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
601
  r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
677
601
  if (r < 0) {
678
551
    sc_log(card->ctx, "sc_card_ctl rc=%d",r);
679
551
    set_string(&p15card->tokeninfo->serial_number, "00000000");
680
551
  } else {
681
50
    sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0);
682
50
    set_string(&p15card->tokeninfo->serial_number, buf);
683
50
  }
684
  /* US gov issued PIVs have CHUID with a FASCN that does not start with 9999 */
685
601
  if (serial.len == 25 && !(serial.value[0] == 0xD4 && serial.value[1] == 0xE7 && serial.value[2] == 0x39 && (serial.value[3] | 0x7F) == 0xFF)) {
686
43
      follows_nist_fascn = 1;
687
43
  }
688
689
601
  sc_log(card->ctx,  "PIV-II adding objects...");
690
691
  /* set other objects */
692
22.8k
  for (i = 0; objects[i].label; i++) {
693
22.2k
    struct sc_pkcs15_data_info obj_info;
694
22.2k
    struct sc_pkcs15_object    obj_obj;
695
696
22.2k
    memset(&obj_info, 0, sizeof(obj_info));
697
22.2k
    memset(&obj_obj, 0, sizeof(obj_obj));
698
22.2k
    sc_pkcs15_format_id(objects[i].id, &obj_info.id);
699
22.2k
    sc_format_path(objects[i].path, &obj_info.path);
700
701
    /* See if the object can not be present on the card */
702
22.2k
    r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &obj_info.path);
703
22.2k
    if (r == 1)
704
12.6k
      continue; /* Not on card, do not define the object */
705
706
9.58k
    strncpy(obj_info.app_label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
707
9.58k
    r = sc_format_oid(&obj_info.app_oid, objects[i].aoid);
708
9.58k
    if (r != SC_SUCCESS)
709
9.58k
      LOG_FUNC_RETURN(card->ctx, r);
710
711
    /* We can not read all the objects, as some need the PIN! */
712
9.58k
    if (objects[i].auth_id)
713
1.80k
      sc_pkcs15_format_id(objects[i].auth_id, &obj_obj.auth_id);
714
715
9.58k
    strncpy(obj_obj.label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
716
9.58k
    obj_obj.flags = objects[i].obj_flags;
717
718
9.58k
    r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT,
719
9.58k
      &obj_obj, &obj_info);
720
721
9.58k
    if (r < 0)
722
9.58k
      LOG_FUNC_RETURN(card->ctx, r);
723
9.58k
  }
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
601
  sc_log(card->ctx,  "PIV-II adding certs...");
737
15.6k
  for (i = 0; i < PIV_NUM_CERTS; i++) {
738
15.0k
    struct sc_pkcs15_cert_info cert_info;
739
15.0k
    struct sc_pkcs15_object    cert_obj;
740
15.0k
    sc_pkcs15_der_t   cert_der;
741
15.0k
    sc_pkcs15_cert_t *cert_out = NULL;
742
15.0k
    int private_obj;
743
744
15.0k
    ckis[i].cert_found = 0;
745
15.0k
    ckis[i].key_alg = -1;
746
15.0k
    ckis[i].pubkey_found = 0;
747
15.0k
    ckis[i].pubkey_from_file = 0;
748
15.0k
    ckis[i].pubkey_len = 0;
749
15.0k
    ckis[i].pubkey_from_cert = NULL;
750
15.0k
    ckis[i].cert_keyUsage = 0;
751
15.0k
    ckis[i].cert_keyUsage_present = 0;
752
15.0k
    ckis[i].pub_usage = 0;
753
15.0k
    ckis[i].priv_usage = 0;
754
755
15.0k
    memset(&cert_info, 0, sizeof(cert_info));
756
15.0k
    memset(&cert_obj,  0, sizeof(cert_obj));
757
758
15.0k
    sc_pkcs15_format_id(certs[i].id, &cert_info.id);
759
15.0k
    cert_info.authority = certs[i].authority;
760
15.0k
    sc_format_path(certs[i].path, &cert_info.path);
761
762
15.0k
    strncpy(cert_obj.label, certs[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
763
15.0k
    cert_obj.flags = certs[i].obj_flags;
764
765
    /* See if the cert might be present or not. */
766
15.0k
    r = sc_card_ctl(card, SC_CARDCTL_PIV_OBJECT_PRESENT, &cert_info.path);
767
15.0k
    if (r == 1) {
768
11.5k
      sc_log(card->ctx,  "Cert can not be present,i=%d", i);
769
11.5k
      continue;
770
11.5k
    }
771
772
3.42k
    private_obj = cert_obj.flags & SC_PKCS15_CO_FLAG_PRIVATE;
773
3.42k
    r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, private_obj);
774
775
3.42k
    if (r) {
776
3.10k
      sc_log(card->ctx,  "No cert found,i=%d", i);
777
3.10k
      continue;
778
3.10k
    }
779
780
325
    ckis[i].cert_found = 1;
781
    /* cache it using the PKCS15 emulation objects */
782
    /* as it does not change */
783
325
    if (cert_der.value) {
784
325
      cert_info.value.value = cert_der.value;
785
325
      cert_info.value.len = cert_der.len;
786
325
      if (!p15card->opts.use_file_cache
787
325
          || (private_obj && !(p15card->opts.use_file_cache & SC_PKCS15_OPTS_CACHE_ALL_FILES))) {
788
325
        cert_info.path.len = 0; /* use in mem cert from now on */
789
325
      }
790
325
    }
791
    /* following will find the cached cert in cert_info */
792
325
    r =  sc_pkcs15_read_certificate(p15card, &cert_info, private_obj, &cert_out);
793
325
    if (r < 0 || cert_out == NULL || cert_out->key == NULL) {
794
225
      sc_log(card->ctx,  "Failed to read/parse the certificate r=%d",r);
795
225
      if (cert_out != NULL)
796
11
        sc_pkcs15_free_certificate(cert_out);
797
225
      free(cert_der.value);
798
225
      continue;
799
225
    }
800
801
    /* set the token name to the name of the CN of the first certificate */
802
100
    if (!token_name) {
803
90
      u8 * cn_name = NULL;
804
90
      size_t cn_len = 0;
805
90
      static const struct sc_object_id cn_oid = {{ 2, 5, 4, 3, -1 }};
806
90
      r = sc_pkcs15_get_name_from_dn(card->ctx, cert_out->subject,
807
90
        cert_out->subject_len, &cn_oid, &cn_name, &cn_len);
808
90
      if (r == SC_SUCCESS) {
809
6
        token_name = malloc (cn_len+1);
810
6
        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
6
        memcpy(token_name, cn_name, cn_len);
818
6
        free(cn_name);
819
6
        token_name[cn_len] = 0;
820
6
        free(p15card->tokeninfo->label);
821
6
        p15card->tokeninfo->label = token_name;
822
6
      }
823
90
    }
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
100
    if (follows_nist_fascn == 0) {
832
74
      struct sc_object_id keyUsage_oid={{2,5,29,15,-1}};
833
74
      int r = 0;
834
835
74
      r = sc_pkcs15_get_bitstring_extension(card->ctx, cert_out,
836
74
        &keyUsage_oid,
837
74
        &ckis[i].cert_keyUsage, NULL);
838
74
      if ( r >= 0)
839
0
        ckis[i].cert_keyUsage_present = 1;
840
        /* TODO if no key usage, we could set all uses */
841
74
    }
842
843
844
100
    ckis[i].key_alg = cert_out->key->algorithm;
845
100
    switch (cert_out->key->algorithm) {
846
16
      case SC_ALGORITHM_RSA:
847
        /* save pubkey_len for pub and priv */
848
16
        ckis[i].pubkey_len = cert_out->key->u.rsa.modulus.len * 8;
849
        /* See RFC 5280 and PKCS#11 V2.40 */
850
16
        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
16
        break;
901
902
84
      case SC_ALGORITHM_EC:
903
84
      case SC_ALGORITHM_EDDSA:
904
84
      case SC_ALGORITHM_XEDDSA:
905
84
        ckis[i].pubkey_len = cert_out->key->u.ec.params.field_length;
906
84
        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
84
        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
100
    }
950
100
    if (i < PIV_NUM_KEYS) { /* Only save pub key if card can have private key */
951
96
      ckis[i].pubkey_from_cert = cert_out->key;
952
96
      cert_out->key = NULL;
953
96
    }
954
100
    sc_pkcs15_free_certificate(cert_out);
955
956
100
    r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
957
100
    if (r < 0) {
958
0
      sc_log(card->ctx,  " Failed to add cert obj r=%d",r);
959
0
      continue;
960
0
    }
961
100
  }
962
963
  /* set pins */
964
601
  sc_log(card->ctx,  "PIV-II adding pins...");
965
2.40k
  for (i = 0; pins[i].label; i++) {
966
1.80k
    struct sc_pkcs15_auth_info pin_info;
967
1.80k
    struct sc_pkcs15_object   pin_obj;
968
1.80k
    const char * label;
969
1.80k
    int pin_ref;
970
971
    /* the SignPIN is only used with minidriver */
972
1.80k
    if (pins[i].cardmod && (strcmp(card->ctx->app_name, "cardmod") != 0))
973
601
      continue;
974
975
1.20k
    memset(&pin_info, 0, sizeof(pin_info));
976
1.20k
    memset(&pin_obj,  0, sizeof(pin_obj));
977
978
1.20k
    pin_info.auth_type = SC_PKCS15_PIN_AUTH_TYPE_PIN;
979
1.20k
    sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id);
980
1.20k
    pin_info.attrs.pin.reference     = pins[i].ref;
981
1.20k
    pin_info.attrs.pin.flags         = pins[i].flags;
982
1.20k
    pin_info.attrs.pin.type          = pins[i].type;
983
1.20k
    pin_info.attrs.pin.min_length    = pins[i].minlen;
984
1.20k
    pin_info.attrs.pin.stored_length = pins[i].storedlen;
985
1.20k
    pin_info.attrs.pin.max_length    = pins[i].maxlen;
986
1.20k
    pin_info.attrs.pin.pad_char      = pins[i].pad_char;
987
1.20k
    pin_info.tries_left              = pins[i].tries_left;
988
1.20k
    sc_format_path(pins[i].path, &pin_info.path);
989
990
1.20k
    label = pins[i].label;
991
1.20k
    if ((i == 0 || pins[i].cardmod) &&
992
601
      sc_card_ctl(card, SC_CARDCTL_PIV_PIN_PREFERENCE,
993
601
          &pin_ref) == 0 &&
994
601
        pin_ref == 0x00) { /* must be 80 for PIV pin, or 00 for Global PIN */
995
1
      pin_info.attrs.pin.reference = pin_ref;
996
1
      label = "Global PIN";
997
1
    }
998
999
1.20k
    strncpy(pin_obj.label, label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1000
1.20k
    pin_obj.flags = pins[i].obj_flags;
1001
1.20k
    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
601
      pin_obj.auth_id.len = 1;
1007
601
      pin_obj.auth_id.value[0] = 2;
1008
601
    }
1009
1010
1.20k
    r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
1011
1.20k
    LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add PIN");
1012
1.20k
  }
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
601
  sc_log(card->ctx,  "PIV-II adding pub keys...");
1020
14.8k
  for (i = 0; i < PIV_NUM_KEYS; i++) {
1021
14.2k
    struct sc_pkcs15_pubkey_info pubkey_info;
1022
14.2k
    struct sc_pkcs15_object     pubkey_obj;
1023
14.2k
    struct sc_pkcs15_pubkey *p15_key = NULL;
1024
1025
14.2k
    memset(&pubkey_info, 0, sizeof(pubkey_info));
1026
14.2k
    memset(&pubkey_obj,  0, sizeof(pubkey_obj));
1027
1028
1029
14.2k
    sc_pkcs15_format_id(pubkeys[i].id, &pubkey_info.id);
1030
14.2k
    pubkey_info.native        = 1;
1031
14.2k
    pubkey_info.key_reference = pubkeys[i].ref;
1032
1033
//    sc_format_path(pubkeys[i].path, &pubkey_info.path);
1034
1035
14.2k
    strncpy(pubkey_obj.label, pubkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1036
1037
14.2k
    pubkey_obj.flags = pubkeys[i].obj_flags;
1038
1039
14.2k
    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
14.2k
    if (ckis[i].cert_found == 0 ) { /*  no cert found */
1049
13.8k
      char * filename = NULL;
1050
1051
13.8k
      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
13.8k
      sc_log(card->ctx, "DEE look for env %s",
1063
13.8k
          pubkeys[i].getenvname?pubkeys[i].getenvname:"NULL");
1064
1065
13.8k
      if (pubkeys[i].getenvname == NULL)
1066
0
        continue;
1067
1068
13.8k
      filename = getenv(pubkeys[i].getenvname);
1069
13.8k
      sc_log(card->ctx, "DEE look for file %s", filename?filename:"NULL");
1070
13.8k
      if (filename == NULL)
1071
13.8k
        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
317
    else if (ckis[i].pubkey_from_cert)   {
1119
95
      r = sc_pkcs15_encode_pubkey_as_spki(card->ctx, ckis[i].pubkey_from_cert,
1120
95
        &pubkey_info.direct.spki.value, &pubkey_info.direct.spki.len);
1121
95
      LOG_TEST_GOTO_ERR(card->ctx, r, "SPKI encode public key error");
1122
1123
85
      pubkey_obj.emulated = ckis[i].pubkey_from_cert;
1124
85
      ckis[i].pubkey_from_cert = NULL;
1125
85
    }
1126
1127
307
    sc_log(card->ctx, "adding pubkey for %d keyalg=%lu", i, ckis[i].key_alg);
1128
307
    switch (ckis[i].key_alg) {
1129
3
      case SC_ALGORITHM_RSA:
1130
3
        if (ckis[i].cert_keyUsage_present) {
1131
0
          pubkey_info.usage =  ckis[i].pub_usage;
1132
3
        } else {
1133
3
          pubkey_info.usage = pubkeys[i].usage_rsa;
1134
3
        }
1135
3
        pubkey_info.modulus_length = ckis[i].pubkey_len;
1136
3
        strncpy(pubkey_obj.label, pubkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1137
1138
        /* should not fail */
1139
3
        r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
1140
3
        LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add RSA pubkey");
1141
1142
3
        ckis[i].pubkey_found = 1;
1143
3
        break;
1144
82
      case SC_ALGORITHM_EC:
1145
82
      case SC_ALGORITHM_EDDSA:
1146
82
      case SC_ALGORITHM_XEDDSA:
1147
82
        if (ckis[i].cert_keyUsage_present) {
1148
0
          pubkey_info.usage = ckis[i].pub_usage;
1149
82
        } else {
1150
82
          pubkey_info.usage = pubkeys[i].usage_ec;
1151
82
        }
1152
1153
82
        pubkey_info.field_length = ckis[i].pubkey_len;
1154
82
        strncpy(pubkey_obj.label, pubkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1155
1156
        /* should not fail */
1157
1158
82
        if (ckis[i].key_alg == SC_ALGORITHM_EDDSA)
1159
0
          r = sc_pkcs15emu_add_eddsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
1160
82
        else if (ckis[i].key_alg == SC_ALGORITHM_XEDDSA)
1161
0
          r = sc_pkcs15emu_add_xeddsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
1162
82
        else
1163
82
          r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
1164
1165
82
        LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add EC pubkey");
1166
1167
82
        ckis[i].pubkey_found = 1;
1168
82
        break;
1169
222
      default:
1170
222
        sc_log(card->ctx, "key_alg %lu not supported", ckis[i].key_alg);
1171
222
        continue;
1172
307
    }
1173
85
    sc_log(card->ctx, "USAGE: cert_keyUsage_present:%d usage:0x%8.8x",
1174
85
        ckis[i].cert_keyUsage_present, pubkey_info.usage);
1175
85
  }
1176
1177
1178
  /* set private keys */
1179
591
  sc_log(card->ctx,  "PIV-II adding private keys...");
1180
14.7k
  for (i = 0; i < PIV_NUM_KEYS; i++) {
1181
14.1k
    struct sc_pkcs15_prkey_info prkey_info;
1182
14.1k
    struct sc_pkcs15_object     prkey_obj;
1183
1184
14.1k
    memset(&prkey_info, 0, sizeof(prkey_info));
1185
14.1k
    memset(&prkey_obj,  0, sizeof(prkey_obj));
1186
1187
14.1k
    if (ckis[i].cert_found == 0 && ckis[i].pubkey_found == 0)
1188
13.8k
      continue; /* i.e. no cert or pubkey */
1189
1190
303
    sc_pkcs15_format_id(prkeys[i].id, &prkey_info.id);
1191
303
    prkey_info.native        = 1;
1192
303
    prkey_info.key_reference = prkeys[i].ref;
1193
303
    sc_format_path(prkeys[i].path, &prkey_info.path);
1194
1195
303
    strncpy(prkey_obj.label, prkeys[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
1196
303
    prkey_obj.flags = prkeys[i].obj_flags;
1197
303
    prkey_obj.user_consent = prkeys[i].user_consent; /* only Sign key */
1198
1199
303
    if (prkeys[i].auth_id)
1200
278
      sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id);
1201
1202
    /* If using minidriver, use Sign PIN  for 9C key */
1203
303
    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
303
    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
303
    switch (ckis[i].key_alg) {
1221
3
      case SC_ALGORITHM_RSA:
1222
3
        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
3
        } else {
1229
3
          prkey_info.usage |= prkeys[i].usage_rsa;
1230
3
        }
1231
3
        prkey_info.modulus_length= ckis[i].pubkey_len;
1232
3
        r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
1233
3
        break;
1234
82
      case SC_ALGORITHM_EC:
1235
82
      case SC_ALGORITHM_EDDSA:
1236
82
      case SC_ALGORITHM_XEDDSA:
1237
82
        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
82
        } else {
1244
82
          prkey_info.usage  |= prkeys[i].usage_ec;
1245
82
        }
1246
82
        prkey_info.field_length = ckis[i].pubkey_len;
1247
82
        sc_log(card->ctx, "DEE added key_alg %2.2lx prkey_obj.flags %8.8x",
1248
82
           ckis[i].key_alg, prkey_obj.flags);
1249
1250
82
        if (ckis[i].key_alg == SC_ALGORITHM_EDDSA)
1251
0
          r = sc_pkcs15emu_add_eddsa_prkey(p15card, &prkey_obj, &prkey_info);
1252
82
        else if (ckis[i].key_alg == SC_ALGORITHM_XEDDSA)
1253
0
          r = sc_pkcs15emu_add_xeddsa_prkey(p15card, &prkey_obj, &prkey_info);
1254
82
        else
1255
82
          r = sc_pkcs15emu_add_ec_prkey(p15card, &prkey_obj, &prkey_info);
1256
82
        break;
1257
218
      default:
1258
218
        sc_log(card->ctx, "Unsupported key_alg %lu", ckis[i].key_alg);
1259
218
        r = 0; /* we just skip this one */
1260
303
    }
1261
303
    sc_log(card->ctx, "USAGE: cert_keyUsage_present:%d usage:0x%8.8x", ckis[i].cert_keyUsage_present, prkey_info.usage);
1262
303
    LOG_TEST_GOTO_ERR(card->ctx, r, "Failed to add Private key");
1263
303
  }
1264
1265
591
  p15card->ops.get_guid = piv_get_guid;
1266
1267
591
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1268
10
err:
1269
260
  for (i = 0; i < PIV_NUM_CERTS; i++) {
1270
250
    sc_pkcs15_free_pubkey(ckis[i].pubkey_from_cert);
1271
250
  }
1272
10
  sc_pkcs15_card_clear(p15card);
1273
10
  LOG_FUNC_RETURN(card->ctx, r);
1274
10
}
1275
1276
int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card,
1277
    struct sc_aid *aid)
1278
10.4k
{
1279
10.4k
  sc_card_t   *card = p15card->card;
1280
10.4k
  sc_context_t    *ctx = card->ctx;
1281
1282
10.4k
  SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
1283
1284
10.4k
  if (piv_detect_card(p15card))
1285
9.85k
    return SC_ERROR_WRONG_CARD;
1286
601
  return sc_pkcs15emu_piv_init(p15card);
1287
10.4k
}