Coverage Report

Created: 2026-03-08 07:02

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