Coverage Report

Created: 2025-12-14 06:58

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