Coverage Report

Created: 2026-07-10 06:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensc/src/libopensc/card-piv.c
Line
Count
Source
1
/*
2
 * card-piv.c: Support for PIV-II from NIST SP800-73
3
 * card-default.c: Support for cards with no driver
4
 *
5
 * Copyright (C) 2001, 2002  Juha Yrjölä <juha.yrjola@iki.fi>
6
 * Copyright (C) 2005-2026  Douglas E. Engert <deengert@gmail.com>
7
 * Copyright (C) 2006, Identity Alliance, Thomas Harning <thomas.harning@identityalliance.com>
8
 * Copyright (C) 2007, EMC, Russell Larner <rlarner@rsa.com>
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 2.1 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, write to the Free Software
22
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23
 */
24
25
#ifdef HAVE_CONFIG_H
26
#include "config.h"
27
#endif
28
29
#include <ctype.h>
30
#include <fcntl.h>
31
#include <limits.h>
32
#include <stdlib.h>
33
#include <string.h>
34
35
#ifdef _WIN32
36
#include <io.h>
37
#else
38
#include <unistd.h>
39
#endif
40
41
#ifdef ENABLE_OPENSSL
42
/* openssl needed for card administration and SM */
43
#include <openssl/evp.h>
44
#include <openssl/pem.h>
45
#include <openssl/rand.h>
46
#include <openssl/sha.h>
47
#if !defined(OPENSSL_NO_EC)
48
#include <openssl/ec.h>
49
#endif
50
#endif
51
52
#include "common/compat_strlcat.h"
53
#include "common/compat_strlcpy.h"
54
#include "internal.h"
55
56
/* 800-73-4 SM and VCI need: ECC, SM and OpenSSL or LibreSSL */
57
#if defined(ENABLE_PIV_SM)
58
#include "compression.h"
59
#include <openssl/cmac.h>
60
#endif
61
62
#include "asn1.h"
63
#include "cardctl.h"
64
#include "simpletlv.h"
65
66
// clang-format off
67
68
enum {
69
  PIV_OBJ_CCC = 0,
70
  PIV_OBJ_CHUI,
71
  /*  PIV_OBJ_UCHUI is not in new with 800-73-2 */
72
  PIV_OBJ_X509_PIV_AUTH,
73
  PIV_OBJ_CHF,
74
  PIV_OBJ_PI,
75
  PIV_OBJ_CHFI,
76
  PIV_OBJ_X509_DS,
77
  PIV_OBJ_X509_KM,
78
  PIV_OBJ_X509_CARD_AUTH,
79
  PIV_OBJ_SEC_OBJ,
80
  PIV_OBJ_DISCOVERY,
81
  PIV_OBJ_HISTORY,
82
  PIV_OBJ_RETIRED_X509_1,
83
  PIV_OBJ_RETIRED_X509_2,
84
  PIV_OBJ_RETIRED_X509_3,
85
  PIV_OBJ_RETIRED_X509_4,
86
  PIV_OBJ_RETIRED_X509_5,
87
  PIV_OBJ_RETIRED_X509_6,
88
  PIV_OBJ_RETIRED_X509_7,
89
  PIV_OBJ_RETIRED_X509_8,
90
  PIV_OBJ_RETIRED_X509_9,
91
  PIV_OBJ_RETIRED_X509_10,
92
  PIV_OBJ_RETIRED_X509_11,
93
  PIV_OBJ_RETIRED_X509_12,
94
  PIV_OBJ_RETIRED_X509_13,
95
  PIV_OBJ_RETIRED_X509_14,
96
  PIV_OBJ_RETIRED_X509_15,
97
  PIV_OBJ_RETIRED_X509_16,
98
  PIV_OBJ_RETIRED_X509_17,
99
  PIV_OBJ_RETIRED_X509_18,
100
  PIV_OBJ_RETIRED_X509_19,
101
  PIV_OBJ_RETIRED_X509_20,
102
  PIV_OBJ_IRIS_IMAGE,
103
  PIV_OBJ_BITGT,
104
  PIV_OBJ_SM_CERT_SIGNER,
105
  PIV_OBJ_PCRDCS,
106
  PIV_OBJ_9B03,
107
  PIV_OBJ_9A06,
108
  PIV_OBJ_9C06,
109
  PIV_OBJ_9D06,
110
  PIV_OBJ_9E06,
111
  PIV_OBJ_8206,
112
  PIV_OBJ_8306,
113
  PIV_OBJ_8406,
114
  PIV_OBJ_8506,
115
  PIV_OBJ_8606,
116
  PIV_OBJ_8706,
117
  PIV_OBJ_8806,
118
  PIV_OBJ_8906,
119
  PIV_OBJ_8A06,
120
  PIV_OBJ_8B06,
121
  PIV_OBJ_8C06,
122
  PIV_OBJ_8D06,
123
  PIV_OBJ_8E06,
124
  PIV_OBJ_8F06,
125
  PIV_OBJ_9006,
126
  PIV_OBJ_9106,
127
  PIV_OBJ_9206,
128
  PIV_OBJ_9306,
129
  PIV_OBJ_9406,
130
  PIV_OBJ_9506,
131
  PIV_OBJ_LAST_ENUM
132
};
133
134
/*
135
 * Flags in the piv_obj_cache:
136
 * PIV_OBJ_CACHE_VALID means the data in the cache can be used.
137
 * It might have zero length indicating that the object was not found.
138
 * PIV_OBJ_CACHE_NOT_PRESENT means do not even try to read the object.
139
 * Either because the object did not parse or
140
 * these objects will only be present if the history object says
141
 * they are on the card, or the discovery or history object in not present.
142
 * If the file listed in the history object offCardCertURL was found,
143
 * its certs will be read into the cache and PIV_OBJ_CACHE_VALID set
144
 * and PIV_OBJ_CACHE_NOT_PRESENT unset.
145
 *
146
 */
147
148
9.25k
#define PIV_OBJ_CACHE_VALID   1
149
1.47k
#define PIV_OBJ_CACHE_COMPRESSED  2
150
152k
#define PIV_OBJ_CACHE_NOT_PRESENT 8
151
152
typedef struct piv_obj_cache {
153
  u8* obj_data;
154
  size_t obj_len;
155
  u8* internal_obj_data; /* like a cert in the object */
156
  size_t internal_obj_len;
157
  int flags;
158
} piv_obj_cache_t;
159
160
enum {
161
  PIV_STATE_NORMAL = 0,
162
  PIV_STATE_MATCH,
163
  PIV_STATE_INIT
164
};
165
166
/* ccc_flags */
167
62
#define PIV_CCC_FOUND   0x00000001
168
21
#define PIV_CCC_F0_PIV    0x00000002
169
11
#define PIV_CCC_F0_CAC    0x00000004
170
15
#define PIV_CCC_F0_JAVA   0x00000008
171
509
#define PIV_CCC_F3_CAC_PKI  0x00000010
172
173
154
#define PIV_CCC_TAG_F0    0xF0
174
156
#define PIV_CCC_TAG_F3    0xF3
175
176
/* 800-73-4 Cipher Suite Table 14 */
177
#define PIV_CS_CS2    0x27
178
#define PIV_CS_CS7    0x2E
179
180
#ifdef ENABLE_PIV_SM
181
#ifdef USE_OPENSSL3_LIBCTX
182
#define PIV_LIBCTX card->ctx->ossl3ctx->libctx
183
#else
184
#define PIV_LIBCTX NULL
185
#endif
186
187
  /* Table 14 and other constants */
188
  typedef struct cipher_suite {
189
    u8 id; /* taken from AID "AC" tag */
190
    int field_length;
191
    int nid;     /* for OpenSSL curves */
192
    struct sc_object_id oid; /* for opensc */
193
    int p1;      /* for APDU */
194
    size_t Qlen; /* size of pubkey 04||x||y for all keys */
195
    size_t AuthCryptogramlen; /* both H and ICC must match */
196
    size_t Zlen; /* size of shared secret from ECDH */
197
    size_t otherinfolen; /* used in 4.1.6  Key Derivation */
198
199
    int o0len; /* first in otherinfo */
200
    u8 o0_char;
201
    size_t CBhlen;
202
    size_t T16Qehlen;
203
    size_t IDsicclen;
204
    size_t Nicclen;
205
    size_t CBicclen; /* last in otherinfo */
206
207
    int naeskeys; /* number of aes key generated */
208
    int aeskeylen; /* size of aes key bytes*/
209
    int kdf_hash_size; /* size of hash in bytes */
210
    EVP_MD *(*kdf_md)(void);
211
    const EVP_CIPHER *(*cipher_cbc)(void);
212
    const EVP_CIPHER *(*cipher_ecb)(void);
213
    char *cipher_cbc_name;
214
    char *cipher_ecb_name;
215
    char *curve_group;
216
  } cipher_suite_t;
217
218
#define PIV_CSS_SIZE 2
219
static cipher_suite_t css[PIV_CSS_SIZE] = {
220
    {PIV_CS_CS2, 256, NID_X9_62_prime256v1, {{1, 2, 840, 10045, 3, 1, 7, -1}},
221
    PIV_CS_CS2, 65, 16, 32, 61,
222
    4, 0x09, 1, 16, 8, 16, 1,
223
    4, 128/8, SHA256_DIGEST_LENGTH,
224
    (EVP_MD *(*)(void)) EVP_sha256,
225
    (const EVP_CIPHER *(*)(void)) EVP_aes_128_cbc,
226
    (const EVP_CIPHER *(*)(void)) EVP_aes_128_ecb,
227
    "aes-128-cbc", "aes-128-ecb",
228
    "prime256v1"},
229
230
    {PIV_CS_CS7, 384, NID_secp384r1, {{1, 3, 132, 0, 34, -1}},
231
    PIV_CS_CS7, 97, 16, 48, 69,
232
    4, 0x0D, 1, 16, 8, 24, 1,
233
    4, 256/8, SHA384_DIGEST_LENGTH,
234
    (EVP_MD *(*)(void)) EVP_sha384,
235
    (const EVP_CIPHER *(*)(void)) EVP_aes_256_cbc,
236
    (const EVP_CIPHER *(*)(void)) EVP_aes_256_ecb,
237
    "aes-256-cbc", "aes-256-ecb",
238
    "secp384r1"}
239
  };
240
241
/* 800-73-4  4.1.5 Card Verifiable Certificates */
242
typedef struct piv_cvc {
243
  sc_pkcs15_der_t der;          // Previous read der
244
  int cpi;            // Certificate profile indicator (0x80)
245
  char issuerID[8];         // Issuer Identification Number
246
  size_t issuerIDlen;         //  8 bytes of sha-1 or 16 byte for GUID
247
  u8  subjectID[16];          //  Subject Identifier (8) or GUID (16)  == CHUI
248
  size_t subjectIDlen;          //  8 bytes of sha-1 or 16 byte for GUID
249
  struct sc_object_id pubKeyOID;        // Public key algorithm object identifier
250
  u8 *publicPoint;          // Public point for ECC
251
  size_t publicPointlen;
252
  int roleID;           // Role Identifier 0x00 or 0x12
253
  u8 *body;           // signed part of CVC in DER
254
  size_t bodylen;
255
  struct sc_object_id  signatureAlgOID;     // Signature Algroithm Identifier
256
  u8 *signature;            // Certificate signature DER
257
  size_t signaturelen;
258
} piv_cvc_t;
259
260
#define PIV_SM_MAX_FIELD_LENGTH  384
261
#define PIV_SM_MAX_MD_LENGTH  SHA384_DIGEST_LENGTH
262
263
#define PIV_SM_FLAGS_SM_CERT_SIGNER_VERIFIED  0x000000001lu
264
#define PIV_SM_FLAGS_SM_CVC_VERIFIED    0X000000002lu
265
#define PIV_SM_FLAGS_SM_IN_CVC_VERIFIED   0x000000004lu
266
#define PIV_SM_FLAGS_SM_CERT_SIGNER_PRESENT 0x000000010lu
267
#define PIV_SM_FLAGS_SM_CVC_PRESENT   0X000000020lu
268
#define PIV_SM_FLAGS_SM_IN_CVC_PRESENT    0x000000040lu
269
#define PIV_SM_FLAGS_SM_IS_ACTIVE   0x000000080lu /* SM has been started */
270
  /* if card supports SP800-73-4 SM: */
271
#define PIV_SM_FLAGS_NEVER      0x000000100lu /* Don't use SM even if card support it */
272
                /* Default is use if card supports it */
273
                /* will use VCI if card supports it for contactless */
274
#define PIV_SM_FLAGS_ALWAYS     0x000000200lu /* Use SM or quit, VCI requires SM */
275
#define PIV_SM_FLAGS_DEFER_OPEN     0x000001000lu /* call sm_open from reader_lock_obtained */
276
#define PIV_SM_VCI_ACTIVE     0x000002000lu   /* VCI is active */
277
#define PIV_SM_GET_DATA_IN_CLEAR    0x000004000lu /* OK to do this GET DATA in the clear */
278
279
typedef struct piv_sm_session {
280
  /* set by piv_sm_open */
281
  int aes_size; /* 128 or 256 */
282
283
  u8 SKcfrm[32];
284
  u8 SKmac[32];
285
  u8 SKenc[32];  /* keys are either AES 128 or AES 256 */
286
  u8 SKrmac[32];
287
  u8 enc_counter[16];
288
  u8 enc_counter_last[16];
289
290
  u8 resp_enc_counter[16];
291
  u8 C_MCV[16];
292
  u8 C_MCV_last[16];
293
  u8 R_MCV[16];
294
  u8 R_MCV_last[16];
295
} piv_sm_session_t;
296
297
#define C_ASN1_PIV_CVC_PUBKEY_SIZE 3
298
  /* ECC key only */
299
static const struct sc_asn1_entry c_asn1_piv_cvc_pubkey[C_ASN1_PIV_CVC_PUBKEY_SIZE] = {
300
  { "publicKeyOID", SC_ASN1_OBJECT, SC_ASN1_UNI | SC_ASN1_OBJECT, 0, NULL, NULL },
301
  { "publicPoint", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 6, SC_ASN1_OPTIONAL | SC_ASN1_ALLOC, NULL, NULL },
302
  { NULL, 0, 0, 0, NULL, NULL }
303
};
304
305
#define C_ASN1_PIV_CVC_DSOBJ_SIZE 2
306
static const struct sc_asn1_entry c_asn1_piv_cvc_dsobj[C_ASN1_PIV_CVC_DSOBJ_SIZE] = {
307
  { "DigitalSignature", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
308
  { NULL, 0, 0, 0, NULL, NULL }
309
};
310
311
#define C_ASN1_PIV_CVC_DSSIG_SIZE 3
312
static const struct sc_asn1_entry c_asn1_piv_cvc_dssig[C_ASN1_PIV_CVC_DSSIG_SIZE] = {
313
  { "signatureAlgorithmID", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
314
  { "signatureValue", SC_ASN1_BIT_STRING_NI, SC_ASN1_TAG_BIT_STRING, SC_ASN1_ALLOC, NULL, NULL },
315
  { NULL, 0, 0, 0, NULL, NULL }
316
};
317
318
#define C_ASN1_PIV_CVC_ALG_ID_SIZE 3
319
static const struct sc_asn1_entry c_asn1_piv_cvc_alg_id[C_ASN1_PIV_CVC_ALG_ID_SIZE] = {
320
  { "signatureAlgorithmOID", SC_ASN1_OBJECT, SC_ASN1_UNI | SC_ASN1_OBJECT, 0, NULL, NULL },
321
  { "nullParam",  SC_ASN1_NULL, SC_ASN1_UNI | SC_ASN1_TAG_NULL, SC_ASN1_OPTIONAL, NULL, NULL },
322
  { NULL, 0, 0, 0, NULL, NULL }
323
};
324
325
#define C_ASN1_PIV_CVC_BODY_SIZE 7
326
static const struct sc_asn1_entry c_asn1_piv_cvc_body[C_ASN1_PIV_CVC_BODY_SIZE] = {
327
  { "certificateProfileIdentifier", SC_ASN1_INTEGER, SC_ASN1_APP | 0x1F29, 0, NULL, NULL },
328
  { "Issuer ID Number", SC_ASN1_OCTET_STRING, SC_ASN1_APP | 2, 0, NULL, NULL },
329
  { "Subject Identifier", SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x1F20, 0, NULL, NULL },
330
  { "publicKey", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F49, 0, NULL, NULL },
331
  { "roleIdentifier", SC_ASN1_CALLBACK, SC_ASN1_APP | 0x1F4C, 0, NULL, NULL },
332
  /* signature is over the above 5 entries  treat roleIdentifier special to get end */
333
  { "DSignatureObject", SC_ASN1_STRUCT, SC_ASN1_APP | 0x1F37, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, NULL, NULL },
334
  { NULL, 0, 0, 0, NULL, NULL }
335
};
336
337
338
#define C_ASN1_PIV_CVC_SIZE 2
339
static const struct sc_asn1_entry c_asn1_piv_cvc[C_ASN1_PIV_CVC_SIZE] = {
340
  { "CVC certificate", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x1F21, 0, NULL, NULL },
341
  { NULL, 0, 0, 0, NULL, NULL }
342
};
343
344
#define C_ASN1_PIV_SM_RESPONSE_SIZE 4
345
static const struct sc_asn1_entry c_asn1_sm_response[C_ASN1_PIV_SM_RESPONSE_SIZE] = {
346
  { "encryptedData",      SC_ASN1_CALLBACK,   SC_ASN1_CTX | 7,        SC_ASN1_OPTIONAL,       NULL, NULL },
347
  { "statusWord",         SC_ASN1_CALLBACK,   SC_ASN1_CTX | 0x19,     0,                      NULL, NULL },
348
  { "mac",                SC_ASN1_CALLBACK,   SC_ASN1_CTX | 0x0E,     0,                      NULL, NULL },
349
  { NULL, 0, 0, 0, NULL, NULL }
350
};
351
352
/*
353
 * SW internal apdu response table.
354
 *
355
 * Override APDU response error codes from iso7816.c to allow
356
 * handling of SM specific error
357
 */
358
static const struct sc_card_error piv_sm_errors[] = {
359
  {0x6882, SC_ERROR_SM, "SM not supported"},
360
  {0x6982, SC_ERROR_SM_NO_SESSION_KEYS, "SM Security status not satisfied"}, /* no session established */
361
  {0x6987, SC_ERROR_SM, "Expected SM Data Object missing"},
362
  {0x6988, SC_ERROR_SM_INVALID_SESSION_KEY, "SM Data Object incorrect"}, /* other process interference */
363
  {0, 0, NULL}
364
};
365
#endif /* ENABLE_PIV_SM */
366
367
/* 800-73-4 3.3.2 Discovery Object - PIN Usage Policy */
368
16
#define PIV_PP_PIN    0x00004000u
369
16
#define PIV_PP_GLOBAL   0x00002000u
370
#define PIV_PP_OCC    0x00001000u
371
#define PIV_PP_VCI_IMPL   0x00000800u
372
#define PIV_PP_VCI_WITHOUT_PC 0x00000400u
373
#define PIV_PP_PIV_PRIMARY  0x00000010u
374
3
#define PIV_PP_GLOBAL_PRIMARY 0x00000020u
375
376
/* init_flags */
377
2.04k
#define PIV_INIT_AID_PARSED     0x00000001u
378
477
#define PIV_INIT_AID_AC_SM      0x00000002u
379
707
#define PIV_INIT_DISCOVERY_PARSED   0x00000004u
380
8
#define PIV_INIT_DISCOVERY_PP     0x00000008u
381
2.13k
#define PIV_INIT_IN_READER_LOCK_OBTAINED  0x00000010u
382
383
#define PIV_INIT_CONTACTLESS      0x00000020u
383
384
#define PIV_PAIRING_CODE_LEN   8
385
386
typedef struct piv_private_data {
387
  struct sc_lv_data aid_der; /* previous aid response to compare */
388
  int enumtag;
389
  int max_object_size; /* use setable option. In case objects get bigger */
390
  int selected_obj; /* The index into the piv_objects last selected */
391
  int return_only_cert; /* return the cert from the object */
392
  int rwb_state; /* first time -1, 0, in middle, 1 at eof */
393
  int operation; /* saved from set_security_env */
394
  unsigned long algorithm; /* saved from set_security_env */
395
  int key_ref; /* saved from set_security_env and */
396
  int alg_id;  /* used in decrypt, signature, derive */
397
  unsigned int alg_ids; /* from AID response, NIST required, card version */
398
  unsigned char * al_label; /* from Select AID Application Label */
399
  int al_labellen;
400
  int key_size; /*  RSA: modulus_bits EC: field_length in bits */
401
  u8* w_buf;   /* write_binary buffer */
402
  size_t w_buf_len; /* length of w_buff */
403
  piv_obj_cache_t obj_cache[PIV_OBJ_LAST_ENUM];
404
  int keysWithOnCardCerts;
405
  int keysWithOffCardCerts;
406
  char * offCardCertURL;
407
  int pin_preference; /* set from Discovery object */
408
  int logged_in;
409
  int pstate;
410
  int pin_cmd_verify;
411
  int context_specific;
412
  unsigned int pin_cmd_verify_sw1;
413
  unsigned int pin_cmd_verify_sw2;
414
  int tries_left; /* SC_PIN_CMD_GET_INFO tries_left from last */
415
  unsigned int card_issues; /* card_issues flags for this card */
416
  int object_test_verify; /* Can test this object to set verification state of card */
417
  int yubico_version; /* 3 byte version number of NEO or Yubikey4  as integer */
418
  unsigned int ccc_flags;     /* From  CCC indicate if CAC card */
419
  unsigned int pin_policy; /* from discovery */
420
  unsigned int init_flags;
421
  u8  csID; /* 800-73-4 Cipher Suite ID 0x27 or 0x2E */
422
#ifdef ENABLE_PIV_SM
423
  cipher_suite_t *cs; /* active cipher_suite */
424
  piv_cvc_t sm_cvc;  /* 800-73-4:  SM CVC Table 15 */
425
  piv_cvc_t sm_in_cvc; /* Intermediate CVC Table 16 */
426
  unsigned long  sm_flags;
427
  unsigned char pairing_code[PIV_PAIRING_CODE_LEN]; /* 8 ASCII digits */
428
  piv_sm_session_t sm_session;
429
#endif /* ENABLE_PIV_SM */
430
} piv_private_data_t;
431
432
433k
#define PIV_DATA(card) ((piv_private_data_t*)card->drv_data)
433
434
struct piv_aid {
435
  int enumtag;
436
  size_t len_short; /* min length without version */
437
  size_t len_long;  /* With version and other stuff */
438
  u8 *value;
439
};
440
441
/*
442
 * The Generic AID entry should be the "A0 00 00 03 08 00 00 10 00 "
443
 * NIST published 800-73 on 10/6/2005
444
 * 800-73-1 March 2006 included Errata
445
 * 800-73-2 Part 1 implies  version is  "02 00"
446
 * i.e. "A0 00 00 03 08 00 00 01 00 02 00".
447
 * but we don't need the version number. But could get it from the PIX.
448
 * Discovery object was added.
449
 *
450
 * 800-73-3 Part 1 now refers to "01 00" i.e. going back to 800-73-1.
451
 * The main differences between 73-2, and 73-3 are the addition of the
452
 * key History object, certs and keys and Iris objects.
453
 * These can be discovered using GET DATA
454
455
 * 800-73-4 Has many changes, including optional Secure Messaging,
456
 * optional Virtual Contact Interface and pairing code.
457
 */
458
459
/* ATRs of cards known to have PIV applet. But must still be tested for a PIV applet */
460
/* Yubico, NitroKey, Token2 are identified by ATR historic bytes */
461
/* PivApplet does not provide ATR historic bytes */
462
463
static const struct sc_atr_table piv_atrs[] = {
464
  /* CAC cards with PIV from: CAC-utilziation-and-variation-matrix-v2.03-20May2016.doc */
465
  /*
466
   * https://www.cac.mil/Common-Access-Card/Developer-Resources/
467
   * https://www.cac.mil/Portals/53/Documents/DoD%20Token%20utilziation%20and%20variation%20matrix%20v2_06_17October2019.docx?ver=2019-10-18-102519-120
468
   */
469
  /* Oberthur Card Systems (PIV Endpoint) with PIV endpoint applet and PIV auth cert OBSOLETE */
470
  { "3B:DB:96:00:80:1F:03:00:31:C0:64:77:E3:03:00:82:90:00:C1", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL },
471
472
  /* Gemalto (PIV Endpoint) with PIV endpoint applet and PIV auth cert OBSOLETE */
473
  { "3B 7D 96 00 00 80 31 80 65 B0 83 11 13 AC 83 00 90 00", NULL, NULL, SC_CARD_TYPE_PIV_II_GEMALTO, 0, NULL },
474
475
  /* Gemalto (PIV Endpoint) 2 entries  2016, 2019 */
476
  { "3B:7D:96:00:00:80:31:80:65:B0:83:11:17:D6:83:00:90:00", NULL, NULL, SC_CARD_TYPE_PIV_II_GEMALTO, 0, NULL },
477
478
  /* Oberthur Card System (PIV Endpoint)  2 entries 2016, 2019 */
479
  { "3B:DB:96:00:80:1F:03:00:31:C0:64:B0:F3:10:00:07:90:00:80", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL },
480
  /* Oberthur Card System  with LCS 0F - Some VA cards have Terminated state */
481
  { "3B:DB:96:00:80:1F:03:00:31:C0:64:B0:F3:10:00:0F:90:00:88", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL },
482
483
  /* Giesecke & Devrient (PIV Endpoint)  2 entries 2016, 2019 */
484
  { "3B:7A:18:00:00:73:66:74:65:20:63:64:31:34:34", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC, 0, NULL },
485
  /* Giesecke & Devrient (CAC PIV Endpoint) 2019 */
486
  { "3B:F9:18:00:00:00:53:43:45:37:20:03:00:20:46", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC, 0, NULL },
487
  /* Giesecke & Devrient SCE7 (PIV-only) (DoD Alternate Token G+D Sm@rtCafe Expert v7.0 144K DI 2025) */
488
  { "3B:F9:96:00:00:80:31:FE:45:53:43:45:37:20:0F:00:20:46:4E", NULL, NULL, SC_CARD_TYPE_PIV_II_GI_DE, 0, NULL },
489
490
  /* IDEMIA (new name for Oberthur) (DoD Alternate Token IDEMIA Cosmo V8.0 2025 */
491
  { "3B:D8:18:00:80:B1:FE:45:1F:07:80:31:C1:64:08:06:92:0F:D5", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL },
492
  { "3b:86:80:01:80:31:c1:52:41:1a:7e", NULL, NULL, SC_CARD_TYPE_PIV_II_OBERTHUR, 0, NULL }, /* contactless */
493
494
  /* Following PIVKEY entries are from Windows registry provided by gw@taglio.com 2022-09-05 */
495
  /* PIVKEY PIVKey Feitian (02) */
496
  { "3b:9f:95:81:31:fe:9f:00:66:46:53:05:10:00:11:71:df:00:00:00:00:00:02", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
497
  /* PIVKey Feitian (7C)  aka C910 contactless */
498
  { "3b:8c:80:01:90:67:46:4a:00:64:16:06:f2:72:7e:00:7c", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
499
  /*PIVKey Feitian (E0)  aka C910 */
500
  { "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:64:16:06:f2:72:7e:00:e0", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
501
  /* PIVKey Feitian (FE)  aka PIVKEY T600 token and T800  on Feitian eJAVA */
502
  { "3b:fc:18:00:00:81:31:80:45:90:67:46:4a:00:64:2d:70:c1:72:fe:e0:fe", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
503
  /* PIVKey JCOP241 (AD) */
504
  { "3b:f9:13:00:00:81:31:fe:45:53:50:49:56:4b:45:59:37:30:ad", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
505
  /* PIVKey JCOP242R2 (16) */
506
  { "3b:88:80:01:50:49:56:4b:45:59:37:30:16", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
507
  /* PIVKey JCOP242R2 (5E) */
508
  { "3b:88:80:01:4a:43:4f:50:76:32:34:31:5e", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
509
  /* PIVKey JCOP242R2 (B7) */
510
  { "3b:f8:13:00:00:81:31:fe:45:4a:43:4f:50:76:32:34:31:b7", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
511
  /* PIVKey JCOP3 (67) */
512
  { "3b:88:80:01:46:49:44:45:53:4d:4f:31:67", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
513
  /* PIVKey JCOP3 (8E) */
514
  { "3b:f8:13:00:00:81:31:fe:45:46:49:44:45:53:4d:4f:31:8e", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
515
  /* PIVKey JCOP31 (57) */
516
  { "3b:f9:18:00:ff:81:31:fe:45:4a:43:4f:50:33:31:56:32:32:57", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
517
  /* PIVKey NXP JCOP (03) */
518
  { "3b:8a:80:01:01:50:49:56:4b:45:59:37:30:16:03", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
519
  /* PIVKey NXP JCOP (FF)  aka CP70 */
520
  { "3b:f8:13:00:00:81:31:fe:45:50:49:56:4b:45:59:37:30:ff", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
521
  /* PIVKey SLE78 (3B) */
522
  { "3b:8d:80:01:53:4c:4a:35:32:47:44:4c:31:32:38:43:52:3b", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
523
  /* PIVKey SLE78 (6D) */
524
  { "3b:88:80:01:00:00:00:11:77:81:83:00:6d", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
525
  /* PIVKey SLE78 (28) aka C980 */
526
  { "3b:f9:96:00:00:81:31:fe:45:53:50:49:56:4b:45:59:37:30:28", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
527
  /* PIVKey SLE78 (44) aka C980 contactless */
528
  { "3b:89:80:01:53:50:49:56:4b:45:59:37:30:44", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
529
  /* PIVKey SLE78 (57B) */
530
  { "3b:fd:96:00:00:81:31:fe:45:53:4c:4a:35:32:47:44:4c:31:32:38:43:52:57", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
531
  /* This ATR is too generic. It will be accepted if Application Label in AID response matches */
532
  /* Which looks like there is no Application Label in AID response of these cards */
533
  /* PivApplet (at least when run in virtual machine) uses the same ATR */
534
  /* PIVKey uTrust (01) ISO 14443 Type B without historical bytes */
535
  /* { "3b:80:80:01:01", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL }, */
536
537
  /* PIVKey uTrust (73) */
538
  { "3b:96:11:81:21:75:75:54:72:75:73:74:73", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
539
  /* PIVKey uTrust FIDO2 (73) */
540
  { "3b:96:11:81:21:75:75:54:72:75:73:74:73", NULL, NULL, SC_CARD_TYPE_PIV_II_PIVKEY, 0, NULL },
541
542
  /* Swissbit iShield Key Pro with PIV endpoint applet */
543
  { "3b:97:11:81:21:75:69:53:68:69:65:6c:64:05", NULL, NULL, SC_CARD_TYPE_PIV_II_SWISSBIT, 0, NULL },
544
545
  /* ID-One PIV 2.4.1 on Cosmo V8.1 NIST sp800-73-4 with Secure Messaging and VCI  2020 */
546
  { "3b:d6:96:00:81:b1:fe:45:1f:87:80:31:c1:52:41:1a:2a", NULL, NULL, SC_CARD_TYPE_PIV_II_800_73_4, 0, NULL },
547
  { "3b:d6:97:00:81:b1:fe:45:1f:87:80:31:c1:52:41:12:23",
548
    "ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:00:00", NULL, SC_CARD_TYPE_PIV_II_800_73_4, 0, NULL },
549
  { "3b:86:80:01:80:31:c1:52:41:12:76", NULL, NULL, SC_CARD_TYPE_PIV_II_800_73_4, 0, NULL }, /* contactless */
550
551
  { NULL, NULL, NULL, 0, 0, NULL }
552
};
553
554
static struct piv_supported_ec_curves {
555
  struct sc_object_id oid;
556
  size_t size;
557
  unsigned int key_type;
558
} ec_curves[] = {
559
    {{{1, 2, 840, 10045, 3, 1, 7, -1}}, 256, SC_ALGORITHM_EC  }, /* secp256r1, nistp256, prime256v1, ansiX9p256r1 */
560
    {{{1, 3, 132, 0, 34, -1}},     384, SC_ALGORITHM_EC    }, /* secp384r1, nistp384, prime384v1, ansiX9p384r1 */
561
    {{{1, 3, 101, 112, -1}},     255, SC_ALGORITHM_EDDSA }, /* RFC8410 OID equivalent to ed25519 */
562
    {{{1, 3, 101, 110, -1}},     255, SC_ALGORITHM_XEDDSA}, /* RFC8410 OID equivalent to curve25519 */
563
    {{{-1}},          0,   0         }  /* This entry must not be touched. */
564
};
565
566
/* all cards must respond to entry 0, some may return different PIX which will accept */
567
static struct piv_aid piv_aids[] = {
568
  {SC_CARD_TYPE_PIV_II_GENERIC, /* Not really card type but what PIV AID is supported */
569
     9, 9, (u8 *) "\xA0\x00\x00\x03\x08\x00\x00\x10\x00" },
570
  {SC_CARD_TYPE_PIV_II_GI_DE, /* bug in some G&D cards in response to select aid */
571
     9, 9, (u8 *) "\xA0\x00\x00\x03\x08\x00\x10\x00\x01" },
572
  {0,  9, 0, NULL }
573
};
574
575
/* card_issues - bugs in PIV implementations requires special handling */
576
12.3k
#define CI_VERIFY_630X          0x00000001U /* VERIFY tries left returns 630X rather then 63CX */
577
103
#define CI_VERIFY_LC0_FAIL        0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */
578
              /* will also test after first PIN verify if protected object can be used instead */
579
680
#define CI_NO_RANDOM          0x00000004U /* can not use Challenge to get random data or no 9B key */
580
0
#define CI_CANT_USE_GETDATA_FOR_STATE     0x00000008U /* No object to test verification inplace of VERIFY Lc=0 */
581
169
#define CI_LEAKS_FILE_NOT_FOUND       0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */
582
2.03k
#define CI_DISCOVERY_USELESS        0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
583
723
#define CI_PIV_AID_LOSE_STATE       0x00000040U /* PIV AID can lose the login state run with out it*/
584
585
282
#define CI_OTHER_AID_LOSE_STATE       0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
586
79
#define CI_NFC_EXPOSE_TOO_MUCH        0x00000200U /* PIN, crypto and objects exposed over NFS in violation of 800-73-3 */
587
588
2.77k
#define CI_NO_EC384         0x00000400U /* does not have EC 384 */
589
673
#define CI_NO_EC          0x00000800U /* No EC at all */
590
591
/* PIV and PIV like cards are know to support these asymmetric algorithm identifiers used in alg_ids */
592
2.01k
#define AI_RSA_1024         0x00000001U
593
2.01k
#define AI_RSA_2048         0x00000002U
594
2.01k
#define AI_RSA_3072         0x00000004U
595
706
#define AI_RSA_4096         0x00000008U
596
1.34k
#define AI_EC_256         0x00000100U
597
1.34k
#define AI_EC_384         0x00000200U
598
2.71k
#define AI_25519          0x00100000U
599
2.64k
#define AI_X25519         0x00200000U
600
/* NIST  cards have or do support these (non SM) algorithm identifiers */
601
1.34k
#define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
602
603
static struct {
604
  unsigned long ai_flag;
605
  unsigned char ai_id;
606
  unsigned long ai_sc_type;
607
  int ai_bits;
608
} ai_map[] = {
609
    { AI_RSA_3072, 0x05, SC_ALGORITHM_RSA, 3072 },
610
    { AI_RSA_1024, 0x06, SC_ALGORITHM_RSA, 1024 },
611
    { AI_RSA_2048, 0x07, SC_ALGORITHM_RSA, 2048 },
612
    { AI_RSA_4096, 0x16, SC_ALGORITHM_RSA,4096 },
613
    { AI_EC_256, 0x11, SC_ALGORITHM_EC, 256 },
614
    { AI_EC_384, 0x14, SC_ALGORITHM_EC, 384 },
615
    { AI_25519, 0xE0, SC_ALGORITHM_EDDSA, 255 },
616
    { AI_X25519, 0xE1, SC_ALGORITHM_XEDDSA, 255 },
617
    { 0, 0, 0, 0 }
618
  };
619
620
/* Application Label from select AID response where ATR can not be matched */
621
static struct {
622
  int al_type;
623
  unsigned char * al_label;
624
  int al_labellen;
625
} al_map[] = {
626
    { SC_CARD_TYPE_PIV_II_PIVAPPLET, (u8 *)"PivApplet v", 11 },
627
    { 0, NULL, 0 }
628
  };
629
630
/*
631
 * Flags in the piv_object:
632
 * PIV_OBJECT_NOT_PRESENT: the presents of the object is
633
 * indicated by the History object.
634
 */
635
636
520
#define PIV_OBJECT_TYPE_CERT    0x01
637
0
#define PIV_OBJECT_TYPE_PUBKEY    0x02
638
291k
#define PIV_OBJECT_NOT_PRESENT    0x04
639
#define PIV_OBJECT_TYPE_CVC   0x08 /* is in cert object */
640
#define PIV_OBJECT_NEEDS_PIN    0x10 /* On both contact and contactless */
641
#define PIV_OBJECT_NEEDS_VCI    0x20 /* NIST sp800-73-4 Requires VCI on contactless and card enforces this. */
642
               /* But also See CI_NFC_EXPOSE_TOO_MUCH for non approved PIV-like cards */
643
644
struct piv_object {
645
  int enumtag;
646
  const char * name;
647
  unsigned int resp_tag;
648
  const char * oidstring;
649
  size_t tag_len;
650
  u8  tag_value[3];
651
  u8  containerid[2]; /* will use as relative paths for simulation */
652
  int flags;              /* object has some internal object like a cert */
653
};
654
655
/* Must be in order, and one per enumerated PIV_OBJ */
656
static const struct piv_object piv_objects[] = {
657
  { PIV_OBJ_CCC, "Card Capability Container",
658
      SC_ASN1_APP | 0x13,
659
      "2.16.840.1.101.3.7.1.219.0", 3, {0x5F, 0xC1, 0x07}, {0xDB, 0x00}, PIV_OBJECT_NEEDS_VCI},
660
  { PIV_OBJ_CHUI, "Card Holder Unique Identifier",
661
      SC_ASN1_APP | 0x13,
662
      "2.16.840.1.101.3.7.2.48.0", 3, {0x5F, 0xC1, 0x02}, {0x30, 0x00}, 0},
663
  { PIV_OBJ_X509_PIV_AUTH, "X.509 Certificate for PIV Authentication",
664
      SC_ASN1_APP | 0x13,
665
      "2.16.840.1.101.3.7.2.1.1", 3, {0x5F, 0xC1, 0x05}, {0x01, 0x01}, PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI} ,
666
  { PIV_OBJ_CHF, "Card Holder Fingerprints",
667
      SC_ASN1_APP | 0x13,
668
      "2.16.840.1.101.3.7.2.96.16", 3, {0x5F, 0xC1, 0x03}, {0x60, 0x10}, PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI},
669
  { PIV_OBJ_PI, "Printed Information",
670
      SC_ASN1_APP | 0x13,
671
      "2.16.840.1.101.3.7.2.48.1", 3, {0x5F, 0xC1, 0x09}, {0x30, 0x01}, PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI},
672
  { PIV_OBJ_CHFI, "Cardholder Facial Images",
673
      SC_ASN1_APP | 0x13,
674
      "2.16.840.1.101.3.7.2.96.48", 3, {0x5F, 0xC1, 0x08}, {0x60, 0x30}, PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI},
675
  { PIV_OBJ_X509_DS, "X.509 Certificate for Digital Signature",
676
      SC_ASN1_APP | 0x13,
677
      "2.16.840.1.101.3.7.2.1.0", 3, {0x5F, 0xC1, 0x0A}, {0x01, 0x00}, PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
678
  { PIV_OBJ_X509_KM, "X.509 Certificate for Key Management",
679
      SC_ASN1_APP | 0x13,
680
      "2.16.840.1.101.3.7.2.1.2", 3, {0x5F, 0xC1, 0x0B}, {0x01, 0x02}, PIV_OBJECT_TYPE_CERT},
681
  { PIV_OBJ_X509_CARD_AUTH, "X.509 Certificate for Card Authentication",
682
      SC_ASN1_APP | 0x13,
683
      "2.16.840.1.101.3.7.2.5.0", 3, {0x5F, 0xC1, 0x01}, {0x05, 0x00}, PIV_OBJECT_TYPE_CERT},
684
  { PIV_OBJ_SEC_OBJ, "Security Object",
685
      SC_ASN1_APP | 0x13,
686
      "2.16.840.1.101.3.7.2.144.0", 3, {0x5F, 0xC1, 0x06}, {0x90, 0x00}, PIV_OBJECT_NEEDS_VCI},
687
  { PIV_OBJ_DISCOVERY, "Discovery Object",
688
      SC_ASN1_APP | SC_ASN1_CONS | 0x1E,
689
      "2.16.840.1.101.3.7.2.96.80", 1, {0x7E}, {0x60, 0x50}, 0},
690
  { PIV_OBJ_HISTORY, "Key History Object",
691
      SC_ASN1_APP | 0x13,
692
      "2.16.840.1.101.3.7.2.96.96", 3, {0x5F, 0xC1, 0x0C}, {0x60, 0x60}, PIV_OBJECT_NEEDS_VCI},
693
694
/* 800-73-3, 21 new objects, 20 history certificates */
695
  { PIV_OBJ_RETIRED_X509_1, "Retired X.509 Certificate for Key Management 1",
696
      SC_ASN1_APP | 0x13,
697
      "2.16.840.1.101.3.7.2.16.1", 3, {0x5F, 0xC1, 0x0D}, {0x10, 0x01},
698
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
699
  { PIV_OBJ_RETIRED_X509_2, "Retired X.509 Certificate for Key Management 2",
700
      SC_ASN1_APP | 0x13,
701
      "2.16.840.1.101.3.7.2.16.2", 3, {0x5F, 0xC1, 0x0E}, {0x10, 0x02},
702
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
703
  { PIV_OBJ_RETIRED_X509_3, "Retired X.509 Certificate for Key Management 3",
704
      SC_ASN1_APP | 0x13,
705
      "2.16.840.1.101.3.7.2.16.3", 3, {0x5F, 0xC1, 0x0F}, {0x10, 0x03},
706
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
707
  { PIV_OBJ_RETIRED_X509_4, "Retired X.509 Certificate for Key Management 4",
708
      SC_ASN1_APP | 0x13,
709
      "2.16.840.1.101.3.7.2.16.4", 3, {0x5F, 0xC1, 0x10}, {0x10, 0x04},
710
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
711
  { PIV_OBJ_RETIRED_X509_5, "Retired X.509 Certificate for Key Management 5",
712
      SC_ASN1_APP | 0x13,
713
      "2.16.840.1.101.3.7.2.16.5", 3, {0x5F, 0xC1, 0x11}, {0x10, 0x05},
714
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
715
  { PIV_OBJ_RETIRED_X509_6, "Retired X.509 Certificate for Key Management 6",
716
      SC_ASN1_APP | 0x13,
717
      "2.16.840.1.101.3.7.2.16.6", 3, {0x5F, 0xC1, 0x12}, {0x10, 0x06},
718
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
719
  { PIV_OBJ_RETIRED_X509_7, "Retired X.509 Certificate for Key Management 7",
720
      SC_ASN1_APP | 0x13,
721
      "2.16.840.1.101.3.7.2.16.7", 3, {0x5F, 0xC1, 0x13}, {0x10, 0x07},
722
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
723
  { PIV_OBJ_RETIRED_X509_8, "Retired X.509 Certificate for Key Management 8",
724
      SC_ASN1_APP | 0x13,
725
      "2.16.840.1.101.3.7.2.16.8", 3, {0x5F, 0xC1, 0x14}, {0x10, 0x08},
726
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
727
  { PIV_OBJ_RETIRED_X509_9, "Retired X.509 Certificate for Key Management 9",
728
      SC_ASN1_APP | 0x13,
729
      "2.16.840.1.101.3.7.2.16.9", 3, {0x5F, 0xC1, 0x15}, {0x10, 0x09},
730
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
731
  { PIV_OBJ_RETIRED_X509_10, "Retired X.509 Certificate for Key Management 10",
732
      SC_ASN1_APP | 0x13,
733
      "2.16.840.1.101.3.7.2.16.10", 3, {0x5F, 0xC1, 0x16}, {0x10, 0x0A},
734
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
735
  { PIV_OBJ_RETIRED_X509_11, "Retired X.509 Certificate for Key Management 11",
736
      SC_ASN1_APP | 0x13,
737
      "2.16.840.1.101.3.7.2.16.11", 3, {0x5F, 0xC1, 0x17}, {0x10, 0x0B},
738
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
739
  { PIV_OBJ_RETIRED_X509_12, "Retired X.509 Certificate for Key Management 12",
740
      SC_ASN1_APP | 0x13,
741
      "2.16.840.1.101.3.7.2.16.12", 3, {0x5F, 0xC1, 0x18}, {0x10, 0x0C},
742
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
743
  { PIV_OBJ_RETIRED_X509_13, "Retired X.509 Certificate for Key Management 13",
744
      SC_ASN1_APP | 0x13,
745
      "2.16.840.1.101.3.7.2.16.13", 3, {0x5F, 0xC1, 0x19}, {0x10, 0x0D},
746
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
747
  { PIV_OBJ_RETIRED_X509_14, "Retired X.509 Certificate for Key Management 14",
748
      SC_ASN1_APP | 0x13,
749
      "2.16.840.1.101.3.7.2.16.14", 3, {0x5F, 0xC1, 0x1A}, {0x10, 0x0E},
750
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
751
  { PIV_OBJ_RETIRED_X509_15, "Retired X.509 Certificate for Key Management 15",
752
      SC_ASN1_APP | 0x13,
753
      "2.16.840.1.101.3.7.2.16.15", 3, {0x5F, 0xC1, 0x1B}, {0x10, 0x0F},
754
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
755
  { PIV_OBJ_RETIRED_X509_16, "Retired X.509 Certificate for Key Management 16",
756
      SC_ASN1_APP | 0x13,
757
      "2.16.840.1.101.3.7.2.16.16", 3, {0x5F, 0xC1, 0x1C}, {0x10, 0x10},
758
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
759
  { PIV_OBJ_RETIRED_X509_17, "Retired X.509 Certificate for Key Management 17",
760
      SC_ASN1_APP | 0x13,
761
      "2.16.840.1.101.3.7.2.16.17", 3, {0x5F, 0xC1, 0x1D}, {0x10, 0x11},
762
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
763
  { PIV_OBJ_RETIRED_X509_18, "Retired X.509 Certificate for Key Management 18",
764
      SC_ASN1_APP | 0x13,
765
      "2.16.840.1.101.3.7.2.16.18", 3, {0x5F, 0xC1, 0x1E}, {0x10, 0x12},
766
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
767
  { PIV_OBJ_RETIRED_X509_19, "Retired X.509 Certificate for Key Management 19",
768
      SC_ASN1_APP | 0x13,
769
      "2.16.840.1.101.3.7.2.16.19", 3, {0x5F, 0xC1, 0x1F}, {0x10, 0x13},
770
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
771
  { PIV_OBJ_RETIRED_X509_20, "Retired X.509 Certificate for Key Management 20",
772
      SC_ASN1_APP | 0x13,
773
      "2.16.840.1.101.3.7.2.16.20", 3, {0x5F, 0xC1, 0x20}, {0x10, 0x14},
774
      PIV_OBJECT_NOT_PRESENT|PIV_OBJECT_TYPE_CERT | PIV_OBJECT_NEEDS_VCI},
775
776
  { PIV_OBJ_IRIS_IMAGE, "Cardholder Iris Images",
777
      SC_ASN1_APP | 0x13,
778
      "2.16.840.1.101.3.7.2.16.21", 3, {0x5F, 0xC1, 0x21}, {0x10, 0x15}, PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI},
779
780
/* 800-73-4, 3 new objects */
781
  { PIV_OBJ_BITGT, "Biometric Information Templates Group Template",
782
       SC_ASN1_APP | SC_ASN1_CONS | 0x1F61,
783
      "2.16.840.1.101.3.7.2.16.22", 2, {0x7F, 0x61}, {0x10, 0x16}, 0},
784
  { PIV_OBJ_SM_CERT_SIGNER, "Secure Messaging Certificate Signer",
785
      SC_ASN1_APP | 0x13,
786
      "2.16.840.1.101.3.7.2.16.23", 3, {0x5F, 0xC1, 0x22}, {0x10, 0x17},
787
      PIV_OBJECT_TYPE_CERT | PIV_OBJECT_TYPE_CVC},
788
  {PIV_OBJ_PCRDCS, "Pairing Code Reference Data Container",
789
      SC_ASN1_APP | 0x13,
790
      "2.16.840.1.101.3.7.2.16.24", 3, {0x5F, 0xC1, 0x23}, {0x10, 0x18}, PIV_OBJECT_NEEDS_PIN | PIV_OBJECT_NEEDS_VCI},
791
792
/* following not standard , to be used by piv-tool only for testing */
793
  { PIV_OBJ_9B03, "3DES-ECB ADM",
794
      SC_ASN1_APP | 0x13,
795
      "2.16.840.1.101.3.7.2.9999.3", 2, {0x9B, 0x03}, {0x9B, 0x03}, 0},
796
  /* Only used when signing a cert req, usually from engine
797
   * after piv-tool generated the key and saved the pub key
798
   * to a file. Note RSA key can be 1024, 2048 or 3072
799
   * but still use the "9x06" name.
800
   */
801
  { PIV_OBJ_9A06, "RSA 9A Pub key from last genkey",
802
      SC_ASN1_APP | 0x13,
803
      "2.16.840.1.101.3.7.2.9999.20", 2, {0x9A, 0x06}, {0x9A, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
804
  { PIV_OBJ_9C06, "Pub 9C key from last genkey",
805
      SC_ASN1_APP | 0x13,
806
      "2.16.840.1.101.3.7.2.9999.21", 2, {0x9C, 0x06}, {0x9C, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
807
  { PIV_OBJ_9D06, "Pub 9D key from last genkey",
808
      SC_ASN1_APP | 0x13,
809
      "2.16.840.1.101.3.7.2.9999.22", 2, {0x9D, 0x06}, {0x9D, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
810
  { PIV_OBJ_9E06, "Pub 9E key from last genkey",
811
      SC_ASN1_APP | 0x13,
812
      "2.16.840.1.101.3.7.2.9999.23", 2, {0x9E, 0x06}, {0x9E, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
813
814
  { PIV_OBJ_8206, "Pub 82 key ",
815
      SC_ASN1_APP | 0x13,
816
      "2.16.840.1.101.3.7.2.9999.101", 2, {0x82, 0x06}, {0x82, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
817
  { PIV_OBJ_8306, "Pub 83 key ",
818
      SC_ASN1_APP | 0x13,
819
      "2.16.840.1.101.3.7.2.9999.102", 2, {0x83, 0x06}, {0x83, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
820
  { PIV_OBJ_8406, "Pub 84 key ",
821
      SC_ASN1_APP | 0x13,
822
      "2.16.840.1.101.3.7.2.9999.103", 2, {0x84, 0x06}, {0x84, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
823
  { PIV_OBJ_8506, "Pub 85 key ",
824
      SC_ASN1_APP | 0x13,
825
      "2.16.840.1.101.3.7.2.9999.104", 2, {0x85, 0x06}, {0x85, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
826
  { PIV_OBJ_8606, "Pub 86 key ",
827
      SC_ASN1_APP | 0x13,
828
      "2.16.840.1.101.3.7.2.9999.105", 2, {0x86, 0x06}, {0x86, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
829
  { PIV_OBJ_8706, "Pub 87 key ",
830
      SC_ASN1_APP | 0x13,
831
      "2.16.840.1.101.3.7.2.9999.106", 2, {0x87, 0x06}, {0x87, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
832
  { PIV_OBJ_8806, "Pub 88 key ",
833
      SC_ASN1_APP | 0x13,
834
      "2.16.840.1.101.3.7.2.9999.107", 2, {0x88, 0x06}, {0x88, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
835
  { PIV_OBJ_8906, "Pub 89 key ",
836
      SC_ASN1_APP | 0x13,
837
      "2.16.840.1.101.3.7.2.9999.108", 2, {0x89, 0x06}, {0x89, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
838
  { PIV_OBJ_8A06, "Pub 8A key ",
839
      SC_ASN1_APP | 0x13,
840
      "2.16.840.1.101.3.7.2.9999.109", 2, {0x8A, 0x06}, {0x8A, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
841
  { PIV_OBJ_8B06, "Pub 8B key ",
842
      SC_ASN1_APP | 0x13,
843
      "2.16.840.1.101.3.7.2.9999.110", 2, {0x8B, 0x06}, {0x8B, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
844
  { PIV_OBJ_8C06, "Pub 8C key ",
845
      SC_ASN1_APP | 0x13,
846
      "2.16.840.1.101.3.7.2.9999.111", 2, {0x8C, 0x06}, {0x8C, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
847
  { PIV_OBJ_8D06, "Pub 8D key ",
848
      SC_ASN1_APP | 0x13,
849
      "2.16.840.1.101.3.7.2.9999.112", 2, {0x8D, 0x06}, {0x8D, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
850
  { PIV_OBJ_8E06, "Pub 8E key ",
851
      SC_ASN1_APP | 0x13,
852
      "2.16.840.1.101.3.7.2.9999.113", 2, {0x8E, 0x06}, {0x8E, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
853
  { PIV_OBJ_8F06, "Pub 8F key ",
854
      SC_ASN1_APP | 0x13,
855
      "2.16.840.1.101.3.7.2.9999.114", 2, {0x8F, 0x06}, {0x8F, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
856
  { PIV_OBJ_9006, "Pub 90 key ",
857
      SC_ASN1_APP | 0x13,
858
      "2.16.840.1.101.3.7.2.9999.115", 2, {0x90, 0x06}, {0x90, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
859
  { PIV_OBJ_9106, "Pub 91 key ",
860
      SC_ASN1_APP | 0x13,
861
      "2.16.840.1.101.3.7.2.9999.116", 2, {0x91, 0x06}, {0x91, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
862
  { PIV_OBJ_9206, "Pub 92 key ",
863
      SC_ASN1_APP | 0x13,
864
      "2.16.840.1.101.3.7.2.9999.117", 2, {0x92, 0x06}, {0x92, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
865
  { PIV_OBJ_9306, "Pub 93 key ",
866
      SC_ASN1_APP | 0x13,
867
      "2.16.840.1.101.3.7.2.9999.118", 2, {0x93, 0x06}, {0x93, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
868
  { PIV_OBJ_9406, "Pub 94 key ",
869
      SC_ASN1_APP | 0x13,
870
      "2.16.840.1.101.3.7.2.9999.119", 2, {0x94, 0x06}, {0x94, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
871
  { PIV_OBJ_9506, "Pub 95 key ",
872
      SC_ASN1_APP | 0x13,
873
      "2.16.840.1.101.3.7.2.9999.120", 2, {0x95, 0x06}, {0x95, 0x06}, PIV_OBJECT_TYPE_PUBKEY},
874
      /*
875
       * "Secure Messaging Certificate Signer" is just a certificate.
876
       * No pub or private key on the card.
877
       */
878
  { PIV_OBJ_LAST_ENUM, "", 0, "", 0, "", "", 0}
879
};
880
// clang-format on
881
882
static struct sc_card_operations piv_ops;
883
884
static struct sc_card_driver piv_drv = {
885
    "Personal Identity Verification Card",
886
    "PIV-II",
887
    &piv_ops,
888
    NULL, 0, NULL};
889
890
static int piv_get_cached_data(sc_card_t *card, int enumtag, u8 **buf, size_t *buf_len);
891
static int piv_cache_internal_data(sc_card_t *card, int enumtag);
892
static int piv_logout(sc_card_t *card);
893
static int piv_match_card_continued(sc_card_t *card);
894
static int piv_obj_cache_free_entry(sc_card_t *card, int enumtag, int flags);
895
static int piv_ai_map_find_by_id(sc_card_t *card, u8);
896
897
#ifdef ENABLE_PIV_SM
898
static void piv_inc(u8 *counter, size_t size);
899
static int piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu);
900
static int piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu);
901
static int piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu);
902
static int piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t len, int depth);
903
static int piv_sm_open(struct sc_card *card);
904
static int piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu);
905
static int piv_sm_close(sc_card_t *card);
906
static void piv_clear_cvc_content(piv_cvc_t *cvc);
907
static void piv_clear_sm_session(piv_sm_session_t *session);
908
static int piv_decode_cvc(sc_card_t *card, u8 **buf, size_t *buflen, piv_cvc_t *cvc);
909
static int piv_parse_pairing_code(sc_card_t *card, const char *option);
910
static int Q2OS(int fsize, u8 *Q, size_t Qlen, u8 *OS, size_t *OSlen);
911
static int piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code);
912
static int piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type,
913
    EVP_PKEY *pkey, u8 *data, size_t data_size,
914
    unsigned char *sig, size_t siglen);
915
static int piv_sm_verify_certs(struct sc_card *card);
916
917
static void
918
piv_inc(u8 *counter, size_t size)
919
{
920
  unsigned int c = 1;
921
  unsigned int b;
922
  int i;
923
  for (i = (int)size - 1; c != 0 && i >= 0; i--) {
924
    b = c + counter[i];
925
    counter[i] = b & 0xff;
926
    c = b >> 8;
927
  }
928
}
929
930
/*
931
 *  Construct SM protected APDU
932
 */
933
934
static int
935
piv_encode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu)
936
{
937
  int r = 0;
938
  piv_private_data_t *priv = PIV_DATA(card);
939
  cipher_suite_t *cs = priv->cs;
940
  u8 pad[16] = {0x80};
941
  u8 zeros[16] = {0x00};
942
  u8 IV[16];
943
  u8 header[16];
944
  int padlen = 16; /* may be less */
945
  u8 *sbuf = NULL;
946
  size_t sbuflen = 0;
947
  int MCVlen = 16;
948
  int enc_datalen = 0;
949
  int T87len;
950
  int T97len = 2 + 1;
951
  int T8Elen = 2 + 8;
952
953
  int outli = 0;
954
  int outl = 0;
955
  int outll = 0;
956
  int outdl = 0;
957
  u8 discard[16];
958
  int macdatalen;
959
  size_t C_MCVlen = 16; /* debugging*/
960
961
  u8 *p;
962
  EVP_CIPHER_CTX *ed_ctx = NULL;
963
#if OPENSSL_VERSION_NUMBER < 0x30000000L
964
  CMAC_CTX *cmac_ctx = NULL;
965
#else
966
  EVP_MAC_CTX *cmac_ctx = NULL;
967
  EVP_MAC *mac = NULL;
968
  OSSL_PARAM cmac_params[2];
969
  size_t cmac_params_n;
970
#endif
971
972
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
973
974
#if OPENSSL_VERSION_NUMBER < 0x30000000L
975
  cmac_ctx = CMAC_CTX_new();
976
  if (cmac_ctx == NULL) {
977
    sc_log_openssl(card->ctx);
978
    r = SC_ERROR_INTERNAL;
979
    goto err;
980
  }
981
#else
982
  mac = EVP_MAC_fetch(PIV_LIBCTX, "cmac", NULL);
983
  cmac_params_n = 0;
984
  cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0);
985
  cmac_params[cmac_params_n] = OSSL_PARAM_construct_end();
986
  if (mac == NULL || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) {
987
    sc_log_openssl(card->ctx);
988
    r = SC_ERROR_INTERNAL;
989
    goto err;
990
  }
991
#endif
992
993
  ed_ctx = EVP_CIPHER_CTX_new();
994
  if (ed_ctx == NULL) {
995
    r = SC_ERROR_INTERNAL;
996
    goto err;
997
  }
998
999
  if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 ||
1000
      EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 ||
1001
      EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.enc_counter, 16) != 1 ||
1002
      EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 ||
1003
      outdl != 0) {
1004
    sc_log_openssl(card->ctx);
1005
    sc_log(card->ctx, "SM encode failed in OpenSSL");
1006
    r = SC_ERROR_INTERNAL;
1007
    goto err;
1008
  }
1009
1010
  sm_apdu->cla = 0x0c;
1011
  sm_apdu->ins = plain->ins;
1012
  sm_apdu->p1 = plain->p1;
1013
  sm_apdu->p2 = plain->p2;
1014
1015
  /*
1016
   * All APDUs will be converted to case as SM data is always sent and received
1017
   * if plain->cse == SC_APDU_CASE_1 it never has the the 0x20 bit set
1018
   * which "let OpenSC decides whether to use short or extended APDUs"
1019
   * PIV SM data added for plain->cse == SC_APDU_CASE_1 will not need extended APDUs.
1020
   *
1021
   * NIST 800-73-4 does not say if cards can or must support extended APDUs
1022
   * they must support command chaining and multiple get response APDUs and
1023
   * all examples use short APDUs. The following keep the option open to use extended
1024
   * APDUs in future specifications or "PIV like" cards are know to
1025
   * support extended APDUs.
1026
   *
1027
   * Turn off the CASE bits, and set CASE 4 in sm_apdu.
1028
   */
1029
1030
  sm_apdu->cse = (plain->cse & ~SC_APDU_SHORT_MASK) | SC_APDU_CASE_4_SHORT;
1031
1032
  p = header; /* to be included in CMAC */
1033
  *p++ = 0x0c;
1034
  *p++ = plain->ins;
1035
  *p++ = plain->p1;
1036
  *p++ = plain->p2;
1037
  memcpy(p, pad, 12);
1038
1039
  /* 800-73-4 say padding is 1 to 16 bytes, with 0x80 0x00... */
1040
1041
  /* may not need enc_data for cse 1 or 2 */
1042
  if (plain->datalen == 0) {
1043
    enc_datalen = 0;
1044
    T87len = 0;
1045
    padlen = 0;
1046
  } else {
1047
    enc_datalen = (int)(((plain->datalen + 15) / 16) * 16); /* may add extra 16 bytes */
1048
    padlen = enc_datalen - (int)plain->datalen;
1049
    r = T87len = sc_asn1_put_tag(0x87, NULL, 1 + enc_datalen, NULL, 0, NULL);
1050
    if (r < 0)
1051
      goto err;
1052
  }
1053
1054
  if (plain->resplen == 0 || plain->le == 0)
1055
    T97len = 0;
1056
1057
  sbuflen = T87len + T97len + T8Elen;
1058
1059
  sbuf = calloc(1, sbuflen);
1060
  if (sbuf == NULL) {
1061
    r = SC_ERROR_OUT_OF_MEMORY;
1062
    goto err;
1063
  }
1064
1065
  p = sbuf;
1066
  if (T87len != 0) {
1067
    r = sc_asn1_put_tag(0x87, NULL, 1 + enc_datalen, sbuf, sbuflen, &p);
1068
    if (r != SC_SUCCESS)
1069
      goto err;
1070
1071
    *p++ = 0x01; /* padding context indicator */
1072
1073
    /* first round encryptes Enc counter with zero IV, and does not save the output */
1074
    if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 ||
1075
        EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 ||
1076
        EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 ||
1077
        EVP_EncryptUpdate(ed_ctx, p, &outl, plain->data, (int)plain->datalen) != 1 ||
1078
        EVP_EncryptUpdate(ed_ctx, p + outl, &outll, pad, padlen) != 1 ||
1079
        EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 ||
1080
        outdl != 0) { /* should not happen */
1081
      sc_log_openssl(card->ctx);
1082
      sc_log(card->ctx, "SM _encode failed in OpenSSL");
1083
      r = SC_ERROR_INTERNAL;
1084
      goto err;
1085
    }
1086
    p += enc_datalen;
1087
  }
1088
1089
  if (T97len) {
1090
    *p++ = 0x97;
1091
    *p++ = 0x01;
1092
    *p++ = plain->le;
1093
  }
1094
  macdatalen = (int)(p - sbuf);
1095
1096
  memcpy(priv->sm_session.C_MCV_last, priv->sm_session.C_MCV, MCVlen); /* save is case fails */
1097
1098
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1099
  if (CMAC_Init(cmac_ctx, priv->sm_session.SKmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 ||
1100
      CMAC_Update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) != 1 ||
1101
      CMAC_Update(cmac_ctx, header, sizeof(header)) != 1 ||
1102
      CMAC_Update(cmac_ctx, sbuf, macdatalen) != 1 ||
1103
      CMAC_Final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen) != 1) {
1104
    sc_log_openssl(card->ctx);
1105
    r = SC_ERROR_INTERNAL;
1106
    goto err;
1107
  }
1108
#else
1109
  if (!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKmac,
1110
          priv->sm_session.aes_size, cmac_params) ||
1111
      !EVP_MAC_update(cmac_ctx, priv->sm_session.C_MCV, MCVlen) ||
1112
      !EVP_MAC_update(cmac_ctx, header, sizeof(header)) ||
1113
      !EVP_MAC_update(cmac_ctx, sbuf, macdatalen) ||
1114
      !EVP_MAC_final(cmac_ctx, priv->sm_session.C_MCV, &C_MCVlen, MCVlen)) {
1115
    sc_log_openssl(card->ctx);
1116
    r = SC_ERROR_INTERNAL;
1117
    goto err;
1118
  }
1119
#endif
1120
1121
  *p++ = 0x8E;
1122
  *p++ = 0x08;
1123
  memcpy(p, priv->sm_session.C_MCV, 8);
1124
  p += 8;
1125
  if (p != sbuf + sbuflen) { /* debugging */
1126
    r = SC_ERROR_INTERNAL;
1127
    goto err;
1128
  }
1129
  sm_apdu->data = sbuf;
1130
  sm_apdu->datalen = sbuflen;
1131
  sbuf = NULL;
1132
1133
  sm_apdu->lc = sm_apdu->datalen;
1134
  if (sm_apdu->datalen > 255)
1135
    sm_apdu->flags |= SC_APDU_FLAGS_CHAINING;
1136
1137
  sm_apdu->resplen = plain->resplen + 40; /* expect at least tagged status and rmac8 */
1138
  sm_apdu->resp = malloc(sm_apdu->resplen);
1139
  if (sm_apdu->resp == NULL) {
1140
    r = SC_ERROR_OUT_OF_MEMORY;
1141
    goto err;
1142
  }
1143
  sm_apdu->le = 256; /* always ask for 256 */
1144
1145
  memcpy(priv->sm_session.enc_counter_last, priv->sm_session.enc_counter, sizeof(priv->sm_session.enc_counter));
1146
  piv_inc(priv->sm_session.enc_counter, sizeof(priv->sm_session.enc_counter));
1147
1148
  r = SC_SUCCESS;
1149
err:
1150
1151
  free(sbuf);
1152
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1153
  CMAC_CTX_free(cmac_ctx);
1154
#else
1155
  EVP_MAC_CTX_free(cmac_ctx);
1156
  EVP_MAC_free(mac);
1157
#endif
1158
1159
  EVP_CIPHER_CTX_free(ed_ctx);
1160
1161
  LOG_FUNC_RETURN(card->ctx, r);
1162
}
1163
1164
static int
1165
piv_get_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu)
1166
{
1167
  int r = SC_SUCCESS;
1168
  piv_private_data_t *priv = PIV_DATA(card);
1169
  cipher_suite_t *cs = priv->cs;
1170
1171
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1172
1173
  if (!plain || !sm_apdu)
1174
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1175
1176
  /* Does card support SM? Should not be here */
1177
  if (priv->csID == 0 || cs == NULL)
1178
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED);
1179
1180
  switch (plain->ins) {
1181
  case 0xCB: /* GET_DATA */
1182
    /* If not contactless, could read in clear */
1183
    /* Discovery object never has PIV_SM_GET_DATA_IN_CLEAR set */
1184
    sc_log(card->ctx, "init_flags:0x%8.8x sm_flags:0x%8.8lx", priv->init_flags, priv->sm_flags);
1185
    if (!(priv->init_flags & PIV_INIT_CONTACTLESS) &&
1186
        !(priv->init_flags & PIV_INIT_IN_READER_LOCK_OBTAINED) &&
1187
        (priv->sm_flags & PIV_SM_GET_DATA_IN_CLEAR)) {
1188
      priv->sm_flags &= ~PIV_SM_GET_DATA_IN_CLEAR;
1189
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED);
1190
    }
1191
    break;
1192
  case 0x20: /* VERIFY */
1193
    break;
1194
  case 0x24: /* CHANGE REFERENCE DATA */
1195
    break;
1196
  case 0x87: /* GENERAL AUTHENTICATE */
1197
    break;
1198
  default: /* just issue the plain apdu */
1199
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_SM_NOT_APPLIED);
1200
  }
1201
1202
  *sm_apdu = calloc(1, sizeof(sc_apdu_t));
1203
  if (*sm_apdu == NULL) {
1204
    return SC_ERROR_OUT_OF_MEMORY;
1205
  }
1206
1207
  r = piv_encode_apdu(card, plain, *sm_apdu);
1208
  if (r < 0 && *sm_apdu) {
1209
    piv_free_sm_apdu(card, NULL, sm_apdu);
1210
  }
1211
1212
  LOG_FUNC_RETURN(card->ctx, r);
1213
}
1214
1215
/* ASN1 callback to save address and len of the object */
1216
static int
1217
piv_get_asn1_obj(sc_context_t *ctx, void *arg, const u8 *obj, size_t len, int depth)
1218
{
1219
  struct sc_lv_data *al = arg;
1220
1221
  if (!arg)
1222
    return SC_ERROR_INTERNAL;
1223
1224
  al->value = (u8 *)obj;
1225
  al->len = len;
1226
  return SC_SUCCESS;
1227
}
1228
1229
static int
1230
piv_decode_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t *sm_apdu)
1231
{
1232
  int r = SC_SUCCESS;
1233
  int i;
1234
  piv_private_data_t *priv = PIV_DATA(card);
1235
  cipher_suite_t *cs = priv->cs;
1236
  struct sc_lv_data ee = {NULL, 0};
1237
  struct sc_lv_data status = {NULL, 0};
1238
  struct sc_lv_data rmac8 = {NULL, 0};
1239
  u8 zeros[16] = {0};
1240
  u8 IV[16];
1241
  u8 *p;
1242
  int outl;
1243
  int outli;
1244
  int outll;
1245
  int outdl;
1246
  u8 lastb[16];
1247
  u8 discard[8];
1248
  u8 *q = NULL;
1249
  int inlen;
1250
  int macdatalen;
1251
1252
  size_t MCVlen = 16;
1253
  size_t R_MCVlen = 0;
1254
1255
  EVP_CIPHER_CTX *ed_ctx = NULL;
1256
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1257
  CMAC_CTX *cmac_ctx = NULL;
1258
#else
1259
  EVP_MAC *mac = NULL;
1260
  EVP_MAC_CTX *cmac_ctx = NULL;
1261
  OSSL_PARAM cmac_params[2];
1262
  size_t cmac_params_n = 0;
1263
#endif
1264
1265
  struct sc_asn1_entry asn1_sm_response[C_ASN1_PIV_SM_RESPONSE_SIZE];
1266
1267
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1268
1269
  sc_copy_asn1_entry(c_asn1_sm_response, asn1_sm_response);
1270
1271
  sc_format_asn1_entry(asn1_sm_response + 0, piv_get_asn1_obj, &ee, 0);
1272
  sc_format_asn1_entry(asn1_sm_response + 1, piv_get_asn1_obj, &status, 0);
1273
  sc_format_asn1_entry(asn1_sm_response + 2, piv_get_asn1_obj, &rmac8, 0);
1274
1275
  r = sc_asn1_decode(card->ctx, asn1_sm_response, sm_apdu->resp, sm_apdu->resplen, NULL, NULL);
1276
1277
  if (r < 0) {
1278
    sc_log(card->ctx, "SM decode failed");
1279
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1280
    goto err;
1281
  }
1282
1283
  if (asn1_sm_response[0].flags & SC_ASN1_PRESENT && /* optional */
1284
      (ee.value == NULL || ee.len <= 2)) {
1285
    sc_log(card->ctx, "SM BER-TLV not valid");
1286
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1287
    goto err;
1288
  }
1289
1290
  if ((asn1_sm_response[1].flags & SC_ASN1_PRESENT) == 0 ||
1291
      (asn1_sm_response[2].flags & SC_ASN1_PRESENT) == 0) {
1292
    sc_log(card->ctx, "SM missing status or R-MAC");
1293
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1294
    goto err;
1295
  }
1296
1297
  if (status.len != 2 ||
1298
      status.value == NULL ||
1299
      rmac8.len != 8 ||
1300
      rmac8.value == NULL) {
1301
    sc_log(card->ctx, "SM status or R-MAC length invalid");
1302
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1303
    goto err;
1304
  }
1305
1306
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1307
  cmac_ctx = CMAC_CTX_new();
1308
  if (cmac_ctx == NULL) {
1309
    sc_log_openssl(card->ctx);
1310
    r = SC_ERROR_INTERNAL;
1311
    goto err;
1312
  }
1313
#else
1314
  mac = EVP_MAC_fetch(PIV_LIBCTX, "cmac", NULL);
1315
  cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0);
1316
  cmac_params[cmac_params_n] = OSSL_PARAM_construct_end();
1317
  if (mac == NULL || (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL) {
1318
    sc_log_openssl(card->ctx);
1319
    r = SC_ERROR_INTERNAL;
1320
    goto err;
1321
  }
1322
#endif
1323
1324
  /*  MCV is first, then BER TLV Encoded Encrypted PIV Data and Status */
1325
  macdatalen = (int)(status.value + status.len - sm_apdu->resp);
1326
1327
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1328
  if (CMAC_Init(cmac_ctx, priv->sm_session.SKrmac, priv->sm_session.aes_size, (*cs->cipher_cbc)(), NULL) != 1 ||
1329
      CMAC_Update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) != 1 ||
1330
      CMAC_Update(cmac_ctx, sm_apdu->resp, macdatalen) != 1 ||
1331
      CMAC_Final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen) != 1) {
1332
    sc_log_openssl(card->ctx);
1333
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1334
    goto err;
1335
  }
1336
#else
1337
  if (!EVP_MAC_init(cmac_ctx, (const unsigned char *)priv->sm_session.SKrmac,
1338
          priv->sm_session.aes_size, cmac_params) ||
1339
      !EVP_MAC_update(cmac_ctx, priv->sm_session.R_MCV, MCVlen) ||
1340
      !EVP_MAC_update(cmac_ctx, sm_apdu->resp, macdatalen) ||
1341
      !EVP_MAC_final(cmac_ctx, priv->sm_session.R_MCV, &R_MCVlen, MCVlen)) {
1342
    sc_log_openssl(card->ctx);
1343
    r = SC_ERROR_INTERNAL;
1344
    goto err;
1345
  }
1346
#endif
1347
1348
  if (memcmp(priv->sm_session.R_MCV, rmac8.value, 8) != 0) {
1349
    sc_log(card->ctx, "SM 8 bytes of R-MAC do not match received R-MAC");
1350
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1351
    goto err;
1352
  }
1353
1354
  ed_ctx = EVP_CIPHER_CTX_new();
1355
  if (ed_ctx == NULL) {
1356
    r = SC_ERROR_INTERNAL;
1357
    goto err;
1358
  }
1359
1360
  /* generate same IV used to encrypt response on card */
1361
  if (EVP_EncryptInit_ex(ed_ctx, (*cs->cipher_ecb)(), NULL, priv->sm_session.SKenc, zeros) != 1 ||
1362
      EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 ||
1363
      EVP_EncryptUpdate(ed_ctx, IV, &outli, priv->sm_session.resp_enc_counter, 16) != 1 ||
1364
      EVP_EncryptFinal_ex(ed_ctx, discard, &outdl) != 1 ||
1365
      outdl != 0) {
1366
    sc_log_openssl(card->ctx);
1367
    sc_log(card->ctx, "SM encode failed in OpenSSL");
1368
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1369
    goto err;
1370
  }
1371
1372
  /* some commands do not have response data */
1373
  if (ee.value == NULL) {
1374
    plain->resplen = 0;
1375
  } else {
1376
    p = ee.value;
1377
    inlen = (int)ee.len;
1378
    if (inlen < 17 || *p != 0x01) { /*padding and padding indicator are required */
1379
      sc_log(card->ctx, "SM padding indicator not 0x01");
1380
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1381
      goto err;
1382
    }
1383
1384
    p++; /* skip padding indicator */
1385
    inlen--;
1386
1387
    if ((inlen % 16) != 0) {
1388
      sc_log(card->ctx, "SM encrypted data not multiple of 16");
1389
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1390
      goto err;
1391
    }
1392
1393
    /*
1394
     * Encrypted data has 1 to 16 pad bytes, so may be 1 to 16 bytes longer
1395
     * then expected. i.e. plain->resp and resplen.So will do last block
1396
     * and recombine.
1397
     */
1398
1399
    inlen -= 16;
1400
    if (plain->resplen < (unsigned)inlen || plain->resp == NULL) {
1401
      sc_log(card->ctx, "SM response will not fit in resp,resplen");
1402
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1403
      goto err;
1404
    }
1405
1406
    q = plain->resp;
1407
1408
    /* first round encryptes counter with zero IV, and does not save the output */
1409
    if (EVP_CIPHER_CTX_reset(ed_ctx) != 1 ||
1410
        EVP_DecryptInit_ex(ed_ctx, (*cs->cipher_cbc)(), NULL, priv->sm_session.SKenc, IV) != 1 ||
1411
        EVP_CIPHER_CTX_set_padding(ed_ctx, 0) != 1 ||
1412
        EVP_DecryptUpdate(ed_ctx, q, &outl, p, inlen) != 1 ||
1413
        EVP_DecryptUpdate(ed_ctx, lastb, &outll, p + inlen, 16) != 1 ||
1414
        EVP_DecryptFinal_ex(ed_ctx, discard, &outdl) != 1 ||
1415
        outdl != 0 ||
1416
        outll != 16) { /* should not happen */
1417
      sc_log_openssl(card->ctx);
1418
      sc_log(card->ctx, "SM _decode failed in OpenSSL");
1419
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1420
      goto err;
1421
    }
1422
1423
    /* unpad last block and get bytes in last block */
1424
    for (i = 15; i > 0; i--) {
1425
      if (lastb[i] == 0x80)
1426
        break;
1427
      if (lastb[i] == 0x00)
1428
        continue;
1429
      sc_log(card->ctx, "SM Padding not correct");
1430
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1431
      goto err;
1432
    }
1433
1434
    if (lastb[i] != 0x80) {
1435
      sc_log(card->ctx, "SM Padding not correct");
1436
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1437
      goto err;
1438
    }
1439
1440
    /* will response fit in plain resp buffer */
1441
    if ((unsigned)inlen + i > plain->resplen || plain->resp == NULL) {
1442
      sc_log(card->ctx, "SM response bigger then resplen");
1443
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1444
      goto err;
1445
    }
1446
1447
    /* copy bytes in last block  if any */
1448
    memcpy(plain->resp + inlen, lastb, i);
1449
    plain->resplen = inlen + i;
1450
  }
1451
1452
  plain->sw1 = *(status.value);
1453
  plain->sw2 = *(status.value + 1);
1454
1455
  piv_inc(priv->sm_session.resp_enc_counter, sizeof(priv->sm_session.resp_enc_counter));
1456
1457
  r = SC_SUCCESS;
1458
err:
1459
  if (r != 0 && plain) {
1460
    plain->sw1 = 0x69;
1461
    plain->sw2 = 0x88;
1462
  }
1463
1464
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1465
  CMAC_CTX_free(cmac_ctx);
1466
#else
1467
  EVP_MAC_CTX_free(cmac_ctx);
1468
  EVP_MAC_free(mac);
1469
#endif
1470
1471
  EVP_CIPHER_CTX_free(ed_ctx);
1472
1473
  LOG_FUNC_RETURN(card->ctx, r);
1474
}
1475
1476
static int
1477
piv_free_sm_apdu(sc_card_t *card, sc_apdu_t *plain, sc_apdu_t **sm_apdu)
1478
{
1479
  int r = SC_SUCCESS;
1480
1481
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1482
1483
  if (!sm_apdu)
1484
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1485
  if (!(*sm_apdu))
1486
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1487
1488
  if (plain) {
1489
    plain->sw1 = (*sm_apdu)->sw1;
1490
    plain->sw2 = (*sm_apdu)->sw2;
1491
    if (((*sm_apdu)->sw1 == 0x90 && (*sm_apdu)->sw2 == 00) ||
1492
        (*sm_apdu)->sw1 == 61) {
1493
      r = piv_decode_apdu(card, plain, *sm_apdu);
1494
      goto err;
1495
    }
1496
    sc_log(card->ctx, "SM response sw1:0x%2.2x sw2:0x%2.2x", plain->sw1, plain->sw2);
1497
    if (plain->sw1 == 0x69 && plain->sw2 == 0x88) {
1498
      /* BUT plain->sw1 and sw2 are not passed back as expected */
1499
      r = SC_ERROR_SM_INVALID_CHECKSUM; /* will use this one one for now */
1500
      goto err;
1501
    } else {
1502
      r = SC_ERROR_SM;
1503
      goto err;
1504
    }
1505
  }
1506
1507
err:
1508
  free((unsigned char **)(*sm_apdu)->data);
1509
  free((*sm_apdu)->resp);
1510
  free(*sm_apdu);
1511
  *sm_apdu = NULL;
1512
1513
  LOG_FUNC_RETURN(card->ctx, r);
1514
}
1515
1516
static int
1517
piv_sm_close(sc_card_t *card)
1518
{
1519
  int r = 0;
1520
  piv_private_data_t *priv = PIV_DATA(card);
1521
1522
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1523
  sc_log(card->ctx, "priv->sm_flags: 0x%8.8lu", priv->sm_flags);
1524
1525
  /* sm.c tries to restart sm. Will defer */
1526
  if ((priv->sm_flags & PIV_SM_FLAGS_SM_IS_ACTIVE)) {
1527
    priv->sm_flags |= PIV_SM_FLAGS_DEFER_OPEN;
1528
    priv->sm_flags &= ~PIV_SM_FLAGS_SM_IS_ACTIVE;
1529
  }
1530
1531
  LOG_FUNC_RETURN(card->ctx, r);
1532
}
1533
1534
static void
1535
piv_clear_cvc_content(piv_cvc_t *cvc)
1536
{
1537
  if (!cvc)
1538
    return;
1539
  free(cvc->body);
1540
  free(cvc->signature);
1541
  free(cvc->publicPoint);
1542
  free(cvc->der.value);
1543
  memset(cvc, 0, sizeof(piv_cvc_t));
1544
  return;
1545
}
1546
1547
static void
1548
piv_clear_sm_session(piv_sm_session_t *session)
1549
{
1550
  if (!session)
1551
    return;
1552
  sc_mem_clear(session, sizeof(piv_sm_session_t));
1553
  return;
1554
}
1555
1556
/*
1557
 * Decode a card verifiable certificate as defined in NIST 800-73-4
1558
 */
1559
static int
1560
piv_decode_cvc(sc_card_t *card, u8 **buf, size_t *buflen,
1561
    piv_cvc_t *cvc)
1562
{
1563
  struct sc_asn1_entry asn1_piv_cvc[C_ASN1_PIV_CVC_SIZE];
1564
  struct sc_asn1_entry asn1_piv_cvc_body[C_ASN1_PIV_CVC_BODY_SIZE];
1565
  struct sc_asn1_entry asn1_piv_cvc_pubkey[C_ASN1_PIV_CVC_PUBKEY_SIZE];
1566
  struct sc_asn1_entry asn1_piv_cvc_dsobj[C_ASN1_PIV_CVC_DSOBJ_SIZE];
1567
  struct sc_asn1_entry asn1_piv_cvc_dssig[C_ASN1_PIV_CVC_DSSIG_SIZE];
1568
  struct sc_asn1_entry asn1_piv_cvc_alg_id[C_ASN1_PIV_CVC_ALG_ID_SIZE];
1569
  struct sc_lv_data roleIDder = {NULL, 0};
1570
  int r;
1571
  const u8 *buf_tmp;
1572
  unsigned int cla_out, tag_out;
1573
  size_t taglen;
1574
  size_t signaturebits;
1575
1576
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1577
1578
  if (buf == NULL || *buf == NULL || cvc == NULL) {
1579
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
1580
  }
1581
1582
  /* If already read and matches previous version return SC_SUCCESS */
1583
  if (cvc->der.value && (cvc->der.len == *buflen) && (memcmp(cvc->der.value, *buf, *buflen) == 0))
1584
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1585
1586
  piv_clear_cvc_content(cvc);
1587
1588
  memset(cvc, 0, sizeof(piv_cvc_t));
1589
  cvc->issuerIDlen = sizeof(cvc->issuerID);
1590
  cvc->subjectIDlen = sizeof(cvc->subjectID);
1591
1592
  sc_copy_asn1_entry(c_asn1_piv_cvc, asn1_piv_cvc);
1593
  sc_copy_asn1_entry(c_asn1_piv_cvc_body, asn1_piv_cvc_body);
1594
  sc_copy_asn1_entry(c_asn1_piv_cvc_pubkey, asn1_piv_cvc_pubkey);
1595
  sc_copy_asn1_entry(c_asn1_piv_cvc_dsobj, asn1_piv_cvc_dsobj);
1596
  sc_copy_asn1_entry(c_asn1_piv_cvc_dssig, asn1_piv_cvc_dssig);
1597
  sc_copy_asn1_entry(c_asn1_piv_cvc_alg_id, asn1_piv_cvc_alg_id);
1598
1599
  sc_format_asn1_entry(asn1_piv_cvc_alg_id, &cvc->signatureAlgOID, NULL, 1);
1600
  sc_format_asn1_entry(asn1_piv_cvc_alg_id + 1, NULL, NULL, 1); /* NULL */
1601
1602
  sc_format_asn1_entry(asn1_piv_cvc_dssig, &asn1_piv_cvc_alg_id, NULL, 1);
1603
  sc_format_asn1_entry(asn1_piv_cvc_dssig + 1, &cvc->signature, &signaturebits, 1);
1604
1605
  sc_format_asn1_entry(asn1_piv_cvc_dsobj, &asn1_piv_cvc_dssig, NULL, 1);
1606
1607
  sc_format_asn1_entry(asn1_piv_cvc_pubkey, &cvc->pubKeyOID, NULL, 1);
1608
  sc_format_asn1_entry(asn1_piv_cvc_pubkey + 1, &cvc->publicPoint, &cvc->publicPointlen, 1);
1609
1610
  sc_format_asn1_entry(asn1_piv_cvc_body, &cvc->cpi, NULL, 1);
1611
  sc_format_asn1_entry(asn1_piv_cvc_body + 1, &cvc->issuerID, &cvc->issuerIDlen, 1);
1612
  sc_format_asn1_entry(asn1_piv_cvc_body + 2, &cvc->subjectID, &cvc->subjectIDlen, 1);
1613
  sc_format_asn1_entry(asn1_piv_cvc_body + 3, &asn1_piv_cvc_pubkey, NULL, 1);
1614
  sc_format_asn1_entry(asn1_piv_cvc_body + 4, piv_get_asn1_obj, &roleIDder, 1);
1615
  sc_format_asn1_entry(asn1_piv_cvc_body + 5, &asn1_piv_cvc_dsobj, NULL, 1);
1616
1617
  sc_format_asn1_entry(asn1_piv_cvc, &asn1_piv_cvc_body, NULL, 1);
1618
1619
  r = sc_asn1_decode(card->ctx, asn1_piv_cvc, *buf, *buflen, NULL, NULL); /*(const u8 **) &buf_tmp, &len);*/
1620
  if (r < 0) {
1621
    piv_clear_cvc_content(cvc);
1622
    sc_log(card->ctx, "Could not decode card verifiable certificate");
1623
    LOG_FUNC_RETURN(card->ctx, r);
1624
  }
1625
1626
  cvc->signaturelen = signaturebits / 8;
1627
1628
  if (roleIDder.len != 1)
1629
    LOG_TEST_RET(card->ctx, SC_ERROR_SM_AUTHENTICATION_FAILED, "roleID wrong length");
1630
1631
  cvc->roleID = *roleIDder.value;
1632
1633
  /* save body der for verification */
1634
  buf_tmp = *buf;
1635
  r = sc_asn1_read_tag(&buf_tmp, *buflen, &cla_out, &tag_out, &taglen);
1636
  LOG_TEST_RET(card->ctx, r, " failed to read tag");
1637
1638
  cvc->bodylen = (roleIDder.value + roleIDder.len) - buf_tmp;
1639
1640
  cvc->body = malloc(cvc->bodylen);
1641
  if (cvc->body == NULL)
1642
    return SC_ERROR_OUT_OF_MEMORY;
1643
  memcpy(cvc->body, buf_tmp, cvc->bodylen);
1644
1645
  /* save to reuse */
1646
  cvc->der.value = malloc(*buflen);
1647
  if (cvc->der.value == NULL) {
1648
    free(cvc->body);
1649
    return SC_ERROR_OUT_OF_MEMORY;
1650
  }
1651
  cvc->der.len = *buflen;
1652
  memcpy(cvc->der.value, *buf, cvc->der.len);
1653
1654
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
1655
}
1656
1657
static int
1658
piv_parse_pairing_code(sc_card_t *card, const char *option)
1659
{
1660
  size_t i;
1661
1662
  if (strlen(option) != PIV_PAIRING_CODE_LEN) {
1663
    sc_log(card->ctx, "pairing code length invalid must be %d", PIV_PAIRING_CODE_LEN);
1664
    return SC_ERROR_INVALID_ARGUMENTS;
1665
  }
1666
  for (i = 0; i < PIV_PAIRING_CODE_LEN; i++) {
1667
    if (!isdigit(option[i])) {
1668
      sc_log(card->ctx, "pairing code must be %d decimal digits", PIV_PAIRING_CODE_LEN);
1669
      return SC_ERROR_INVALID_ARGUMENTS;
1670
    }
1671
  }
1672
  return SC_SUCCESS;
1673
}
1674
#endif
1675
1676
static int
1677
piv_load_options(sc_card_t *card)
1678
673
{
1679
673
  int r;
1680
673
  size_t i, j;
1681
673
  scconf_block **found_blocks, *block;
1682
1683
#ifdef ENABLE_PIV_SM
1684
  piv_private_data_t *priv = PIV_DATA(card);
1685
  const char *option = NULL;
1686
  int piv_pairing_code_found = 0;
1687
  int piv_use_sm_found = 0;
1688
1689
  /* pairing code is 8 decimal digits and is card specific */
1690
  if ((option = getenv("PIV_PAIRING_CODE")) != NULL) {
1691
    sc_log(card->ctx, "getenv(\"PIV_PAIRING_CODE\") found");
1692
    if (piv_parse_pairing_code(card, option) == SC_SUCCESS) {
1693
      memcpy(priv->pairing_code, option, PIV_PAIRING_CODE_LEN);
1694
      piv_pairing_code_found = 1;
1695
    }
1696
  }
1697
1698
  if ((option = getenv("PIV_USE_SM")) != NULL) {
1699
    sc_log(card->ctx, "getenv(\"PIV_USE_SM\")=\"%s\"", option);
1700
    if (!strcmp(option, "never")) {
1701
      priv->sm_flags |= PIV_SM_FLAGS_NEVER;
1702
      piv_use_sm_found = 1;
1703
    } else if (!strcmp(option, "always")) {
1704
      priv->sm_flags |= PIV_SM_FLAGS_ALWAYS;
1705
      piv_use_sm_found = 1;
1706
    } else {
1707
      sc_log(card->ctx, "Invalid piv_use_sm: \"%s\"", option);
1708
    }
1709
  }
1710
#endif
1711
1712
1.34k
  for (i = 0; card->ctx->conf_blocks[i]; i++) {
1713
673
    found_blocks = scconf_find_blocks(card->ctx->conf, card->ctx->conf_blocks[i],
1714
673
        "card_driver", "PIV-II");
1715
673
    if (!found_blocks)
1716
0
      continue;
1717
1718
673
    for (j = 0, block = found_blocks[j]; block; j++, block = found_blocks[j]) {
1719
1720
#ifdef ENABLE_PIV_SM
1721
      /*
1722
       * "piv_use_sm" if card supports NIST sp800-73-4 sm, when should it be used
1723
       * never - use card like 800-73-3, i.e. contactless is very limited on
1724
       * true PIV cards. Some  PIV-like" card may allow this.
1725
       * this security risk
1726
       * always - Use even for contact interface.
1727
       * PINS, crypto and reading of object will not show up in logs
1728
       * or over network.
1729
       */
1730
1731
      if (piv_use_sm_found == 0) {
1732
        option = scconf_get_str(block, "piv_use_sm", "default");
1733
        sc_log(card->ctx, "conf: \"piv_use_sm\"=\"%s\"", option);
1734
        if (!strcmp(option, "default")) {
1735
          /* no new flags */
1736
        } else if (!strcmp(option, "never")) {
1737
          priv->sm_flags |= PIV_SM_FLAGS_NEVER;
1738
        } else if (!strcmp(option, "always")) {
1739
          priv->sm_flags |= PIV_SM_FLAGS_ALWAYS;
1740
        } else {
1741
          sc_log(card->ctx, "Invalid piv_use_sm: \"%s\"", option);
1742
        }
1743
      }
1744
1745
      /* This is really a card specific value and should not be in the conf file */
1746
      if (piv_pairing_code_found == 0) {
1747
        option = scconf_get_str(block, "piv_pairing_code", NULL);
1748
        if (option && piv_parse_pairing_code(card, option) == SC_SUCCESS) {
1749
          memcpy(priv->pairing_code, option, PIV_PAIRING_CODE_LEN);
1750
        }
1751
      }
1752
#endif
1753
0
    }
1754
673
    free(found_blocks);
1755
673
  }
1756
673
  r = SC_SUCCESS;
1757
673
  return r;
1758
673
}
1759
1760
static int
1761
piv_find_obj_by_containerid(sc_card_t *card, const u8 *str)
1762
46.7k
{
1763
46.7k
  int i;
1764
1765
46.7k
  LOG_FUNC_CALLED(card->ctx);
1766
46.7k
  sc_log(card->ctx, "str=0x%02X%02X\n", str[0], str[1]);
1767
1768
974k
  for (i = 0; piv_objects[i].enumtag < PIV_OBJ_LAST_ENUM; i++) {
1769
972k
    if (str[0] == piv_objects[i].containerid[0] && str[1] == piv_objects[i].containerid[1])
1770
972k
      LOG_FUNC_RETURN(card->ctx, i);
1771
972k
  }
1772
1773
2.19k
  LOG_FUNC_RETURN(card->ctx, -1);
1774
2.19k
}
1775
1776
/*
1777
 * Send a command and receive data. There is always something to send.
1778
 * Used by  GET DATA, PUT DATA, GENERAL AUTHENTICATE
1779
 * and GENERATE ASYMMETRIC KEY PAIR.
1780
 */
1781
1782
static int
1783
piv_general_io(sc_card_t *card, int ins, int p1, int p2,
1784
    const u8 *sendbuf, size_t sendbuflen, u8 *recvbuf,
1785
    size_t recvbuflen)
1786
6.66k
{
1787
6.66k
  int r;
1788
6.66k
  sc_apdu_t apdu;
1789
1790
6.66k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1791
1792
6.66k
  r = sc_lock(card);
1793
6.66k
  if (r != SC_SUCCESS)
1794
6.66k
    LOG_FUNC_RETURN(card->ctx, r);
1795
1796
6.66k
  sc_format_apdu(card, &apdu,
1797
6.66k
      recvbuf ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT,
1798
6.66k
      ins, p1, p2);
1799
6.66k
  apdu.flags |= SC_APDU_FLAGS_CHAINING;
1800
#ifdef ENABLE_PIV_SM
1801
  if (card->sm_ctx.sm_mode != SM_MODE_NONE && sendbuflen > 255) {
1802
    /* tell apdu.c to not do the chaining, let the SM get_apdu do it */
1803
    apdu.flags |= SC_APDU_FLAGS_SM_CHAINING;
1804
  }
1805
#endif
1806
6.66k
  apdu.lc = sendbuflen;
1807
6.66k
  apdu.datalen = sendbuflen;
1808
6.66k
  apdu.data = sendbuf;
1809
1810
6.66k
  if (recvbuf && recvbuflen) {
1811
6.66k
    apdu.le = (recvbuflen > 256) ? 256 : recvbuflen;
1812
6.66k
    apdu.resplen = recvbuflen;
1813
6.66k
  } else {
1814
0
    apdu.le = 0;
1815
0
    apdu.resplen = 0;
1816
0
  }
1817
6.66k
  apdu.resp = recvbuf;
1818
1819
  /* with new adpu.c and chaining, this actually reads the whole object */
1820
6.66k
  r = sc_transmit_apdu(card, &apdu);
1821
1822
  /* adpu will not have sw1,sw2 set because sc_sm_single_transmit called sc_sm_stop, */
1823
6.66k
  if (r < 0) {
1824
61
    sc_log(card->ctx, "Transmit failed");
1825
61
    goto err;
1826
61
  }
1827
1828
6.60k
  if (apdu.sw1 == 0x69 && apdu.sw2 == 0x88)
1829
19
    r = SC_ERROR_SM_INVALID_SESSION_KEY;
1830
6.58k
  else
1831
6.58k
    r = sc_check_sw(card, apdu.sw1, apdu.sw2);
1832
1833
6.60k
  if (r < 0) {
1834
5.31k
    sc_log(card->ctx, "Card returned error ");
1835
5.31k
    goto err;
1836
5.31k
  }
1837
1838
1.28k
  r = (int)apdu.resplen;
1839
1840
6.66k
err:
1841
6.66k
  sc_unlock(card);
1842
6.66k
  LOG_FUNC_RETURN(card->ctx, r);
1843
6.66k
}
1844
1845
#ifdef ENABLE_PIV_SM
1846
/* convert q as 04||x||y used in standard point formats to expanded leading
1847
 * zeros and concatenated X||Y as specified in SP80056A Appendix C.2
1848
 * Field-Element-to-Byte-String Conversion which
1849
 * OpenSSL has already converted X and Y to big endian and skipped leading
1850
 * zero bytes.
1851
 */
1852
static int
1853
Q2OS(int fsize, u8 *Q, size_t Qlen, u8 *OS, size_t *OSlen)
1854
{
1855
  size_t i;
1856
  size_t f = fsize / 8;
1857
1858
  i = (Qlen - 1) / 2;
1859
1860
  if (!OS || *OSlen < f * 2 || !Q || i > f)
1861
    return SC_ERROR_INTERNAL;
1862
1863
  memset(OS, 0, f * 2);
1864
  /* Check this if x and y have leading zero bytes,
1865
   * In UNCOMPRESSED FORMAT, x and Y must be same length, to tell when
1866
   * one ends and the other starts */
1867
  memcpy(OS + f - i, Q + 1, i);
1868
  memcpy(OS + 2 * f - i, Q + f + 1, i);
1869
  *OSlen = f * 2;
1870
  return 0;
1871
}
1872
1873
/*
1874
 * if needed, send VCI pairing code to card just after the
1875
 * SM key establishment. Called from piv_sm_open under same lock
1876
 */
1877
static int
1878
piv_send_vci_pairing_code(struct sc_card *card, u8 *paring_code)
1879
{
1880
  int r;
1881
  piv_private_data_t *priv = PIV_DATA(card);
1882
  sc_apdu_t plain;
1883
  sc_apdu_t sm_apdu;
1884
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1885
1886
  if (priv->pin_policy & PIV_PP_VCI_WITHOUT_PC)
1887
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_SUCCESS); /* Not needed */
1888
1889
  if ((priv->pin_policy & PIV_PP_VCI_IMPL) == 0)
1890
    SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NO_CARD_SUPPORT);
1891
1892
  sc_format_apdu(card, &plain, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x98);
1893
  plain.datalen = plain.lc = 8;
1894
  plain.data = paring_code;
1895
  plain.resp = NULL;
1896
  plain.resplen = plain.le = 0;
1897
1898
  memset(&sm_apdu, 0, sizeof(sm_apdu));
1899
  /* build sm_apdu and set alloc sm_apdu.resp */
1900
  r = piv_encode_apdu(card, &plain, &sm_apdu);
1901
  if (r < 0) {
1902
    free(sm_apdu.resp);
1903
    sc_log(card->ctx, "piv_encode_apdu failed");
1904
    LOG_FUNC_RETURN(card->ctx, r);
1905
  }
1906
1907
  sm_apdu.flags += SC_APDU_FLAGS_NO_SM; /* run as is */
1908
  r = sc_transmit_apdu(card, &sm_apdu);
1909
  if (r < 0) {
1910
    free(sm_apdu.resp);
1911
    sc_log(card->ctx, "transmit failed");
1912
    LOG_FUNC_RETURN(card->ctx, r);
1913
  }
1914
1915
  r = piv_decode_apdu(card, &plain, &sm_apdu);
1916
  free(sm_apdu.resp);
1917
  LOG_TEST_RET(card->ctx, r, "piv_decode_apdu failed");
1918
1919
  r = sc_check_sw(card, plain.sw1, plain.sw2);
1920
  if (r < 0)
1921
    r = SC_ERROR_PIN_CODE_INCORRECT;
1922
1923
  LOG_FUNC_RETURN(card->ctx, r);
1924
}
1925
1926
/* Verify one signature using pubkey */
1927
static int
1928
piv_sm_verify_sig(struct sc_card *card, const EVP_MD *type,
1929
    EVP_PKEY *pkey,
1930
    u8 *data, size_t data_size,
1931
    unsigned char *sig, size_t siglen)
1932
{
1933
  piv_private_data_t *priv = PIV_DATA(card);
1934
  cipher_suite_t *cs = priv->cs;
1935
  int r = 0;
1936
  EVP_MD_CTX *md_ctx = NULL;
1937
1938
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1939
1940
  if (cs == NULL) {
1941
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1942
    goto err;
1943
  }
1944
1945
  if ((md_ctx = EVP_MD_CTX_new()) == NULL ||
1946
      EVP_DigestVerifyInit(md_ctx, NULL, type, NULL, pkey) != 1 ||
1947
      EVP_DigestVerifyUpdate(md_ctx, data, data_size) != 1 ||
1948
      EVP_DigestVerifyFinal(md_ctx, sig, siglen) != 1) {
1949
    sc_log_openssl(card->ctx);
1950
    sc_log(card->ctx, "EVP_DigestVerifyFinal failed");
1951
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1952
    goto err;
1953
  }
1954
  r = SC_SUCCESS;
1955
err:
1956
  EVP_MD_CTX_free(md_ctx);
1957
  LOG_FUNC_RETURN(card->ctx, r);
1958
}
1959
1960
/*
1961
 * If sm_in_cvc is present, verify PIV_OBJ_SM_CERT_SIGNER signed sm_in_cvc
1962
 * and sm_in_cvc signed sm_cvc.
1963
 * If sm_in_cvc is not present verify PIV_OBJ_SM_CERT_SIGNER signed sm_cvc.
1964
 */
1965
1966
static int
1967
piv_sm_verify_certs(struct sc_card *card)
1968
{
1969
  piv_private_data_t *priv = PIV_DATA(card);
1970
  cipher_suite_t *cs = priv->cs;
1971
  int r = 0;
1972
  u8 *cert_blob_unzipped = NULL; /* free */
1973
  u8 *cert_blob = NULL;        /* do not free */
1974
  size_t cert_bloblen = 0;
1975
1976
  u8 *rbuf; /* do not free*/
1977
  size_t rbuflen;
1978
  X509 *cert = NULL;
1979
  EVP_PKEY *cert_pkey = NULL; /* do not free */
1980
  EVP_PKEY *in_cvc_pkey = NULL;
1981
#if OPENSSL_VERSION_NUMBER < 0x30000000L
1982
  EC_GROUP *in_cvc_group = NULL;
1983
  EC_POINT *in_cvc_point = NULL;
1984
  EC_KEY *in_cvc_eckey = NULL;
1985
#else
1986
  EVP_PKEY_CTX *in_cvc_pkey_ctx = NULL;
1987
  OSSL_PARAM params[3];
1988
  size_t params_n;
1989
#endif
1990
1991
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
1992
1993
  if (cs == NULL) {
1994
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
1995
    goto err;
1996
  }
1997
1998
  /*
1999
   * Get the PIV_OBJ_SM_CERT_SIGNER and optional sm_in_cvc in cache
2000
   * both are in same object. Rbuf, and rbuflen are needed but not used here
2001
   * sm_cvc and sm_in_cvc both have EC_keys sm_in_cvc may have RSA signature
2002
   */
2003
  r = piv_get_cached_data(card, PIV_OBJ_SM_CERT_SIGNER, &rbuf, &rbuflen);
2004
  if (r < 0) {
2005
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2006
    goto err;
2007
  }
2008
  r = piv_cache_internal_data(card, PIV_OBJ_SM_CERT_SIGNER);
2009
  if (r < 0) {
2010
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2011
    goto err;
2012
  }
2013
2014
  priv->sm_flags |= PIV_SM_FLAGS_SM_CERT_SIGNER_PRESENT; /* set for debugging */
2015
2016
  /* get PIV_OBJ_SM_CERT_SIGNER cert DER  from cache */
2017
  if (priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].flags & PIV_OBJ_CACHE_COMPRESSED) {
2018
#ifdef ENABLE_ZLIB
2019
    if (SC_SUCCESS != sc_decompress_alloc(&cert_blob_unzipped, &cert_bloblen,
2020
              priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_data,
2021
              priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_len,
2022
              COMPRESSION_AUTO)) {
2023
      sc_log(card->ctx, "PIV decompression of SM CERT_SIGNER failed");
2024
      r = SC_ERROR_OBJECT_NOT_VALID;
2025
      goto err;
2026
    }
2027
    cert_blob = cert_blob_unzipped;
2028
#else
2029
    sc_log(card->ctx, "PIV compression not supported, no zlib");
2030
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2031
#endif
2032
2033
  } else {
2034
    cert_blob = priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_data;
2035
    cert_bloblen = priv->obj_cache[PIV_OBJ_SM_CERT_SIGNER].internal_obj_len;
2036
  }
2037
2038
  if (cert_blob == NULL || cert_bloblen == 0) {
2039
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2040
    goto err;
2041
  }
2042
2043
  if ((cert = d2i_X509(NULL, (const u8 **)&cert_blob, cert_bloblen)) == NULL ||
2044
      (cert_pkey = X509_get0_pubkey(cert)) == NULL) {
2045
    sc_log_openssl(card->ctx);
2046
    sc_log(card->ctx, "OpenSSL failed to get pubkey from SM_CERT_SIGNER");
2047
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2048
    goto err;
2049
  }
2050
2051
  /* if intermediate sm_in_cvc present, cert signed it and sm_cvc is signed by sm_in_cvc */
2052
  if (priv->sm_flags & PIV_SM_FLAGS_SM_IN_CVC_PRESENT) {
2053
    r = piv_sm_verify_sig(card, cs->kdf_md(), cert_pkey,
2054
        priv->sm_in_cvc.body, priv->sm_in_cvc.bodylen,
2055
        priv->sm_in_cvc.signature, priv->sm_in_cvc.signaturelen);
2056
    if (r < 0) {
2057
      sc_log(card->ctx, "sm_in_cvc signature invalid");
2058
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2059
      goto err;
2060
    }
2061
2062
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2063
    if ((in_cvc_group = EC_GROUP_new_by_curve_name(cs->nid)) == NULL ||
2064
        (in_cvc_pkey = EVP_PKEY_new()) == NULL ||
2065
        (in_cvc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL ||
2066
        (in_cvc_point = EC_POINT_new(in_cvc_group)) == NULL ||
2067
        EC_POINT_oct2point(in_cvc_group, in_cvc_point,
2068
            priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen, NULL) <= 0 ||
2069
        EC_KEY_set_public_key(in_cvc_eckey, in_cvc_point) <= 0 ||
2070
        EVP_PKEY_set1_EC_KEY(in_cvc_pkey, in_cvc_eckey) != 1) {
2071
      sc_log_openssl(card->ctx);
2072
      sc_log(card->ctx, "OpenSSL failed to set EC pubkey, during verify");
2073
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2074
      goto err;
2075
    }
2076
#else
2077
    params_n = 0;
2078
    params[params_n++] = OSSL_PARAM_construct_utf8_string("group", cs->curve_group, 0);
2079
    params[params_n++] = OSSL_PARAM_construct_octet_string("pub",
2080
        priv->sm_in_cvc.publicPoint, priv->sm_in_cvc.publicPointlen);
2081
    params[params_n] = OSSL_PARAM_construct_end();
2082
2083
    if (!(in_cvc_pkey_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) ||
2084
        !EVP_PKEY_fromdata_init(in_cvc_pkey_ctx) ||
2085
        !EVP_PKEY_fromdata(in_cvc_pkey_ctx, &in_cvc_pkey, EVP_PKEY_PUBLIC_KEY, params) ||
2086
        !in_cvc_pkey) {
2087
      sc_log_openssl(card->ctx);
2088
      sc_log(card->ctx, "OpenSSL failed to set EC pubkey, during verify");
2089
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2090
      goto err;
2091
    }
2092
#endif
2093
    r = piv_sm_verify_sig(card, cs->kdf_md(), in_cvc_pkey,
2094
        priv->sm_cvc.body, priv->sm_cvc.bodylen,
2095
        priv->sm_cvc.signature, priv->sm_cvc.signaturelen);
2096
2097
  } else { /* cert signed  sm_cvc */
2098
    r = piv_sm_verify_sig(card, cs->kdf_md(), cert_pkey,
2099
        priv->sm_cvc.body, priv->sm_cvc.bodylen,
2100
        priv->sm_cvc.signature, priv->sm_cvc.signaturelen);
2101
  }
2102
  if (r < 0) {
2103
    sc_log(card->ctx, "sm_cvc signature invalid");
2104
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2105
    goto err;
2106
  }
2107
2108
  /* cert chain signatures match for oncard certs */
2109
2110
err:
2111
  X509_free(cert);
2112
  free(cert_blob_unzipped);
2113
2114
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2115
  EC_GROUP_free(in_cvc_group);
2116
  EC_POINT_free(in_cvc_point);
2117
  EC_KEY_free(in_cvc_eckey);
2118
#else
2119
  EVP_PKEY_CTX_free(in_cvc_pkey_ctx);
2120
#endif
2121
  EVP_PKEY_free(in_cvc_pkey);
2122
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
2123
}
2124
2125
/*
2126
 * NIST SP800-73-4  4.1 The key Establishment Protocol
2127
 * Variable names and Steps  are based on Client Application (h)
2128
 * and PIV Card Application (icc)
2129
 * Capital leters used for variable, and lower case for subscript names
2130
 */
2131
static int
2132
piv_sm_open(struct sc_card *card)
2133
{
2134
  piv_private_data_t *priv = PIV_DATA(card);
2135
  cipher_suite_t *cs = priv->cs;
2136
  int r = 0;
2137
  int i;
2138
  int reps;
2139
  u8 CBh;
2140
  u8 CBicc;
2141
  u8 *p;
2142
2143
  /* ephemeral EC key */
2144
  EVP_PKEY_CTX *eph_ctx = NULL;
2145
  EVP_PKEY *eph_pkey = NULL;
2146
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2147
  EC_KEY *eph_eckey = NULL;   /* don't free _get0_*/
2148
  const EC_GROUP *eph_group = NULL; /* don't free _get0_ */
2149
#else
2150
  OSSL_PARAM eph_params[5];
2151
  size_t eph_params_n;
2152
  size_t Qehxlen = 0;
2153
  u8 *Qehx = NULL;
2154
#endif
2155
  size_t Qehlen = 0;
2156
  u8 Qeh[2 * PIV_SM_MAX_FIELD_LENGTH / 8 + 1]; /*  big enough for 384 04||x||y  if x and y have leading zeros, length may be less */
2157
  size_t Qeh_OSlen = 0;
2158
  u8 Qeh_OS[2 * PIV_SM_MAX_FIELD_LENGTH / 8]; /* no leading 04, with leading zeros in X and Y */
2159
  size_t Qsicc_OSlen = 0;
2160
  u8 Qsicc_OS[2 * PIV_SM_MAX_FIELD_LENGTH / 8]; /* no leading 04, with leading zeros  in X and Y */
2161
2162
  /* pub EC key from card Cicc in sm_cvc */
2163
  EVP_PKEY_CTX *Cicc_ctx = NULL;
2164
  EVP_PKEY *Cicc_pkey = NULL;
2165
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2166
  EC_KEY *Cicc_eckey = NULL;
2167
  EC_POINT *Cicc_point = NULL;
2168
  EC_GROUP *Cicc_group = NULL;
2169
#endif
2170
2171
  /* shared secret key Z */
2172
  EVP_PKEY_CTX *Z_ctx = NULL;
2173
  u8 *Z = NULL;
2174
  size_t Zlen = 0;
2175
2176
  u8 IDsh[8] = {0};
2177
  unsigned long pid;
2178
2179
  u8 *sbuf = NULL;
2180
  size_t sbuflen;
2181
  int len2a, len2b;
2182
2183
  u8 rbuf[4096];
2184
  size_t rbuflen = sizeof(rbuf);
2185
2186
  const u8 *body, *payload;
2187
  size_t bodylen, payloadlen;
2188
  u8 Nicc[24]; /* nonce */
2189
  u8 AuthCryptogram[16];
2190
2191
  u8 *cvcder = NULL;
2192
  size_t cvclen = 0;
2193
  size_t len; /* temp len */
2194
2195
  u8 *kdf_in = NULL;
2196
  size_t kdf_inlen = 0;
2197
  unsigned int hashlen = 0;
2198
  u8 aeskeys[SHA384_DIGEST_LENGTH * 3] = {0}; /*  4 keys, Hash function is run 2 or 3 times max is 3 * 384/8 see below */
2199
  EVP_MD_CTX *hash_ctx = NULL;
2200
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2201
  CMAC_CTX *cmac_ctx = NULL;
2202
#else
2203
  EVP_MAC *mac = NULL;
2204
  EVP_MAC_CTX *cmac_ctx = NULL;
2205
  OSSL_PARAM cmac_params[2];
2206
  size_t cmac_params_n = 0;
2207
  OSSL_PARAM Cicc_params[3];
2208
  size_t Cicc_params_n = 0;
2209
#endif
2210
2211
  u8 IDsicc[8]; /* will only use 8 bytes for step H6 */
2212
2213
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2214
2215
  /*
2216
   * The SM routines try and call this on their own.
2217
   * This routine should only be called by the card driver.
2218
   * which has set PIV_SM_FLAGS_DEFER_OPEN and unset in
2219
   * in reader_lock_obtained
2220
   * after testing PIC applet is active so SM is setup in same transaction
2221
   * as the command we are trying to run with SM.
2222
   * this avoids situation where the SM is established, and then reset by
2223
   * some other application without getting anything done or in
2224
   * a loop, each trying to reestablish a SM session and run command.
2225
   */
2226
  if (!(priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) {
2227
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED);
2228
  }
2229
  if (cs == NULL)
2230
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
2231
2232
  r = sc_lock(card);
2233
  if (r != SC_SUCCESS) {
2234
    sc_log(card->ctx, "sc_lock failed");
2235
    return r;
2236
  }
2237
2238
  /* use for several hash operations */
2239
  if ((hash_ctx = EVP_MD_CTX_new()) == NULL) {
2240
    r = SC_ERROR_OUT_OF_MEMORY;
2241
    goto err;
2242
  }
2243
2244
  /* Step 1 set CBh = 0 */
2245
  CBh = 0;
2246
2247
  /* Step H2 generate ephemeral EC */
2248
2249
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2250
  if ((eph_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL ||
2251
      EVP_PKEY_keygen_init(eph_ctx) <= 0 ||
2252
      EVP_PKEY_CTX_set_ec_paramgen_curve_nid(eph_ctx, cs->nid) <= 0 ||
2253
      EVP_PKEY_keygen(eph_ctx, &eph_pkey) <= 0 ||
2254
      (eph_eckey = EVP_PKEY_get0_EC_KEY(eph_pkey)) == NULL ||
2255
      (eph_group = EC_KEY_get0_group(eph_eckey)) == NULL ||
2256
      (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey),
2257
           POINT_CONVERSION_UNCOMPRESSED, NULL, Qehlen, NULL)) <= 0 || /* get length */
2258
      Qehlen > cs->Qlen ||
2259
      (Qehlen = EC_POINT_point2oct(eph_group, EC_KEY_get0_public_key(eph_eckey),
2260
           POINT_CONVERSION_UNCOMPRESSED, Qeh, Qehlen, NULL)) <= 0 ||
2261
      Qehlen > cs->Qlen) {
2262
    sc_log_openssl(card->ctx);
2263
    sc_log(card->ctx, "OpenSSL failed to create ephemeral EC key");
2264
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2265
    goto err;
2266
  }
2267
#else
2268
  /* generate Qeh */
2269
  eph_params_n = 0;
2270
  eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string("group", cs->curve_group, 0);
2271
  eph_params[eph_params_n++] = OSSL_PARAM_construct_utf8_string("point-format", "uncompressed", 0);
2272
  eph_params[eph_params_n] = OSSL_PARAM_construct_end();
2273
  if (!(eph_ctx = EVP_PKEY_CTX_new_from_name(PIV_LIBCTX, "EC", NULL)) ||
2274
      !EVP_PKEY_keygen_init(eph_ctx) ||
2275
      !EVP_PKEY_CTX_set_params(eph_ctx, eph_params) ||
2276
      !EVP_PKEY_generate(eph_ctx, &eph_pkey) ||
2277
      !(Qehxlen = EVP_PKEY_get1_encoded_public_key(eph_pkey, &Qehx)) ||
2278
      !Qehx ||
2279
      Qehxlen > cs->Qlen) {
2280
    sc_log_openssl(card->ctx);
2281
    sc_log(card->ctx, "OpenSSL failed to create ephemeral EC key");
2282
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2283
    goto err;
2284
  }
2285
  memcpy(Qeh, Qehx, Qehxlen);
2286
  Qehlen = Qehxlen;
2287
#endif
2288
2289
  /* For later use, get  Qeh without 04 and full size  X || Y */
2290
  Qeh_OSlen = sizeof(Qeh_OS);
2291
  if (Q2OS(cs->field_length, Qeh, Qehlen, Qeh_OS, &Qeh_OSlen)) {
2292
    sc_log(card->ctx, "Q2OS for Qeh failed");
2293
    r = SC_ERROR_INTERNAL;
2294
    goto err;
2295
  }
2296
2297
  r = len2a = sc_asn1_put_tag(0x81, NULL, 1 + sizeof(IDsh) + Qehlen, NULL, 0, NULL);
2298
  if (r < 0)
2299
    goto err;
2300
  r = len2b = sc_asn1_put_tag(0x80, NULL, 0, NULL, 0, NULL);
2301
  if (r < 0)
2302
    goto err;
2303
  sbuflen = r = sc_asn1_put_tag(0x7C, NULL, len2a + len2b, NULL, 0, NULL);
2304
  if (r < 0)
2305
    goto err;
2306
2307
  sbuf = malloc(sbuflen);
2308
  if (sbuf == NULL) {
2309
    r = SC_ERROR_OUT_OF_MEMORY;
2310
    goto err;
2311
  }
2312
  p = sbuf;
2313
2314
  r = sc_asn1_put_tag(0x7C, NULL, len2a + len2b, sbuf, sbuflen, &p);
2315
  if (r != SC_SUCCESS)
2316
    goto err;
2317
2318
  r = sc_asn1_put_tag(0x81, NULL, 1 + sizeof(IDsh) + Qehlen, p, sbuflen - (p - sbuf), &p);
2319
  if (r != SC_SUCCESS)
2320
    goto err;
2321
2322
  /* Step H1 set CBh to 0x00 */
2323
  *p++ = CBh;
2324
2325
#ifdef WIN32
2326
  pid = (unsigned long)GetCurrentProcessId();
2327
#else
2328
  pid = (unsigned long)getpid(); /* use PID as our ID so different from other processes */
2329
#endif
2330
  memcpy(IDsh, &pid, MIN(sizeof(pid), sizeof(IDsh)));
2331
  memcpy(p, IDsh, sizeof(IDsh));
2332
  p += sizeof(IDsh);
2333
  memcpy(p, Qeh, Qehlen);
2334
  p += Qehlen;
2335
2336
  r = sc_asn1_put_tag(0x82, NULL, 0, p, sbuflen - (p - sbuf), &p); /* null data */
2337
  if (r != SC_SUCCESS)
2338
    goto err;
2339
2340
  /* Step H3 send CBh||IDsh|| Qeh  Qeh in 04||x||y */
2341
  /* Or call sc_transmit directly */
2342
  r = piv_general_io(card, 0x87, cs->p1, 0x04, sbuf, (p - sbuf), rbuf, rbuflen);
2343
  if (r <= 0)
2344
    goto err;
2345
2346
  rbuflen = r;
2347
  p = rbuf;
2348
2349
  body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x7C, &bodylen);
2350
  if (body == NULL || bodylen < 20 || rbuf[0] != 0x7C) {
2351
    sc_log(card->ctx, "SM response data to short");
2352
    r = SC_ERROR_SM_NO_SESSION_KEYS;
2353
    goto err;
2354
  }
2355
2356
  payload = sc_asn1_find_tag(card->ctx, body, bodylen, 0x82, &payloadlen);
2357
  if (payload == NULL || payloadlen < 1 + cs->Nicclen + cs->AuthCryptogramlen || *body != 0x82) {
2358
    sc_log(card->ctx, "SM response data to short");
2359
    r = SC_ERROR_SM_NO_SESSION_KEYS;
2360
    goto err;
2361
  }
2362
2363
  /* payload is CBicc (1) || Nicc (16 or 24) || AuthCryptogram (CMAC 16 or 16) ||Cicc (variable) */
2364
  p = (u8 *)payload;
2365
2366
  /* Step H4 check CBicc == 0x00 */
2367
  CBicc = *p++;
2368
  if (CBicc != 0x00) { /* CBicc must be  zero */
2369
    sc_log(card->ctx, "SM card did not accept request");
2370
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2371
    goto err;
2372
  }
2373
2374
  memcpy(Nicc, p, cs->Nicclen);
2375
  p += cs->Nicclen;
2376
2377
  memcpy(AuthCryptogram, p, cs->AuthCryptogramlen);
2378
  p += cs->AuthCryptogramlen;
2379
2380
  if (p > payload + payloadlen) {
2381
    sc_log(card->ctx, "SM card CVC is to short");
2382
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2383
    goto err;
2384
  }
2385
  cvclen = len = payloadlen - (p - payload);
2386
  if (len) {
2387
    cvcder = p; /* in rbuf */
2388
2389
    r = piv_decode_cvc(card, &p, &len, &priv->sm_cvc);
2390
    if (r != SC_SUCCESS) {
2391
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2392
      goto err;
2393
    }
2394
    priv->sm_flags |= PIV_SM_FLAGS_SM_CVC_PRESENT;
2395
  }
2396
2397
  /* Step H5 Verify Cicc CVC and pubkey */
2398
  /* Verify Cicc (sm_cvc) is signed by sm_in_cvc or PIV_OBJ_SM_CERT_SIGNER  */
2399
  /* sm_in_cvc is signed by PIV_OBJ_SM_CERT_SIGNER */
2400
2401
  /* Verify the cert chain is valid. */
2402
  r = piv_sm_verify_certs(card);
2403
  if (r < 0) {
2404
    sc_log(card->ctx, "SM  piv_sm_verify_certs r:%d", r);
2405
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2406
    goto err;
2407
  }
2408
2409
  /* Step H6  need left most 8 bytes of hash of sm_cvc */
2410
  {
2411
    u8 hash[SHA256_DIGEST_LENGTH] = {0};
2412
    const u8 *tag;
2413
    size_t taglen;
2414
    const u8 *tmpder;
2415
    size_t tmpderlen;
2416
2417
    if ((tag = sc_asn1_find_tag(card->ctx, cvcder, cvclen, 0x7F21, &taglen)) == NULL ||
2418
        *cvcder != 0x7F || *(cvcder + 1) != 0x21) {
2419
2420
      r = SC_ERROR_INTERNAL;
2421
      goto err;
2422
    }
2423
2424
    /* debug choice */
2425
    tmpder = cvcder;
2426
    tmpderlen = cvclen;
2427
2428
    if (EVP_DigestInit(hash_ctx, EVP_sha256()) != 1 ||
2429
        EVP_DigestUpdate(hash_ctx, tmpder, tmpderlen) != 1 ||
2430
        EVP_DigestFinal_ex(hash_ctx, hash, NULL) != 1) {
2431
      sc_log_openssl(card->ctx);
2432
      sc_log(card->ctx, "IDsicc hash failed");
2433
      r = SC_ERROR_INTERNAL;
2434
      goto err;
2435
    }
2436
    memcpy(IDsicc, hash, sizeof(IDsicc)); /* left 8 bytes */
2437
  }
2438
2439
  /* Step H7 get the cards public key Qsicc into OpenSSL Cicc_eckey */
2440
2441
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2442
  if ((Cicc_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL)) == NULL ||
2443
      (Cicc_group = EC_GROUP_new_by_curve_name(cs->nid)) == NULL ||
2444
      (Cicc_pkey = EVP_PKEY_new()) == NULL ||
2445
      (Cicc_eckey = EC_KEY_new_by_curve_name(cs->nid)) == NULL ||
2446
      (Cicc_point = EC_POINT_new(Cicc_group)) == NULL ||
2447
      EC_POINT_oct2point(Cicc_group, Cicc_point,
2448
          priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, NULL) <= 0 ||
2449
      EC_KEY_set_public_key(Cicc_eckey, Cicc_point) <= 0 ||
2450
      EVP_PKEY_set1_EC_KEY(Cicc_pkey, Cicc_eckey) <= 0) {
2451
    sc_log_openssl(card->ctx);
2452
    sc_log(card->ctx, "OpenSSL failed to get card's EC pubkey");
2453
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2454
    goto err;
2455
  }
2456
#else
2457
  Cicc_params_n = 0;
2458
  Cicc_params[Cicc_params_n++] = OSSL_PARAM_construct_utf8_string("group", cs->curve_group, 0);
2459
  Cicc_params[Cicc_params_n++] = OSSL_PARAM_construct_octet_string("pub",
2460
      priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen);
2461
  Cicc_params[Cicc_params_n] = OSSL_PARAM_construct_end();
2462
2463
  if (!(Cicc_ctx = EVP_PKEY_CTX_new_from_name(NULL, "EC", NULL)) ||
2464
      !EVP_PKEY_fromdata_init(Cicc_ctx) ||
2465
      !EVP_PKEY_fromdata(Cicc_ctx, &Cicc_pkey, EVP_PKEY_PUBLIC_KEY, Cicc_params) ||
2466
      !Cicc_pkey) {
2467
    sc_log_openssl(card->ctx);
2468
    sc_log(card->ctx, "OpenSSL failed to set EC pubkey for Cicc");
2469
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2470
    goto err;
2471
  }
2472
#endif
2473
2474
  /* Qsicc without 04 and expanded x||y */
2475
  Qsicc_OSlen = sizeof(Qsicc_OS);
2476
  if (Q2OS(cs->field_length, priv->sm_cvc.publicPoint, priv->sm_cvc.publicPointlen, Qsicc_OS, &Qsicc_OSlen)) {
2477
    sc_log(card->ctx, "Q2OS for Qsicc failed");
2478
    r = SC_ERROR_INTERNAL;
2479
    goto err;
2480
  }
2481
2482
  /* Step H8 Compute the shared secret Z */
2483
  if ((Z_ctx = EVP_PKEY_CTX_new(eph_pkey, NULL)) == NULL ||
2484
      EVP_PKEY_derive_init(Z_ctx) <= 0 ||
2485
      EVP_PKEY_derive_set_peer(Z_ctx, Cicc_pkey) <= 0 ||
2486
      EVP_PKEY_derive(Z_ctx, NULL, &Zlen) <= 0 ||
2487
      Zlen != cs->Zlen ||
2488
      (Z = malloc(Zlen)) == NULL ||
2489
      EVP_PKEY_derive(Z_ctx, Z, &Zlen) <= 0 ||
2490
      Zlen != cs->Zlen) {
2491
    sc_log_openssl(card->ctx);
2492
    sc_log(card->ctx, "OpenSSL failed to create secret Z");
2493
    r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2494
    goto err;
2495
  }
2496
2497
  sc_log(card->ctx, "debug Zlen:%" SC_FORMAT_LEN_SIZE_T "u Z[0]:0x%2.2x", Zlen, Z[0]);
2498
2499
  /* Step H9 zeroize deh from step H2 */
2500
  EVP_PKEY_free(eph_pkey); /* OpenSSL  BN_clear_free calls OPENSSL_cleanse */
2501
  eph_pkey = NULL;
2502
2503
  /* Step H10 Create AES session Keys */
2504
  /* kdf in is 4byte counter || Z || otherinfo  800-56A 5.8.1 */
2505
2506
  kdf_inlen = 4 + Zlen + cs->otherinfolen;
2507
  kdf_in = malloc(kdf_inlen);
2508
  if (kdf_in == NULL) {
2509
    r = SC_ERROR_OUT_OF_MEMORY;
2510
    goto err;
2511
  }
2512
  p = kdf_in;
2513
  *p++ = 0x00;
2514
  *p++ = 0x00;
2515
  *p++ = 0x00;
2516
  *p++ = 0x01;
2517
  memcpy(p, Z, cs->Zlen);
2518
  p += Zlen;
2519
2520
  /* otherinfo */
2521
  *p++ = cs->o0len;
2522
  for (i = 0; i < cs->o0len; i++)
2523
    *p++ = cs->o0_char; /* 0x09 or 0x0d */
2524
2525
  *p++ = sizeof(IDsh);
2526
  memcpy(p, IDsh, sizeof(IDsh));
2527
  p += sizeof(IDsh);
2528
2529
  *p++ = cs->CBhlen;
2530
  memcpy(p, &CBh, cs->CBhlen);
2531
  p += cs->CBhlen;
2532
2533
  *p++ = cs->T16Qehlen;
2534
  /* First 16 bytes of Qeh without 04 800-56A Appendix C.2 */
2535
  memcpy(p, Qeh_OS, cs->T16Qehlen);
2536
  p += cs->T16Qehlen;
2537
2538
  *p++ = cs->IDsicclen;
2539
  memcpy(p, IDsicc, cs->IDsicclen);
2540
  p += cs->IDsicclen;
2541
2542
  *p++ = cs->Nicclen;
2543
  memcpy(p, Nicc, cs->Nicclen);
2544
  p += cs->Nicclen;
2545
2546
  *p++ = cs->CBicclen;
2547
  memcpy(p, &CBicc, cs->CBicclen);
2548
  p += cs->CBicclen;
2549
2550
  if (p != kdf_in + kdf_inlen) {
2551
    r = SC_ERROR_INTERNAL;
2552
    goto err;
2553
  }
2554
2555
  /* 4 keys needs reps =  ceil (naeskeys * aeskeylen) / kdf_hash_size) */
2556
  /* 800-56A-2007, 5.8.1 Process and 800-56C rev 3 2018 4.1 Process. */
2557
  /* so it is 2 times for 128 or 3 times for 256 bit AES keys */
2558
  p = aeskeys; /* 4 keys + overflow */
2559
  reps = (cs->naeskeys * cs->aeskeylen + cs->kdf_hash_size - 1) / (cs->kdf_hash_size);
2560
2561
  EVP_MD_CTX_reset(hash_ctx);
2562
  for (i = 0; i < reps; i++) {
2563
    if (EVP_DigestInit(hash_ctx, (*cs->kdf_md)()) != 1 ||
2564
        EVP_DigestUpdate(hash_ctx, kdf_in, kdf_inlen) != 1 ||
2565
        EVP_DigestFinal_ex(hash_ctx, p, &hashlen) != 1) {
2566
      sc_log_openssl(card->ctx);
2567
      sc_log(card->ctx, "KDF hash failed");
2568
      r = SC_ERROR_INTERNAL;
2569
      goto err;
2570
    }
2571
    kdf_in[3]++; /* inc the counter */
2572
    p += cs->kdf_hash_size;
2573
  }
2574
2575
  /* copy keys used for APDU */
2576
  memset(&priv->sm_session, 0, sizeof(piv_sm_session_t)); /* clear */
2577
  priv->sm_session.aes_size = cs->aeskeylen;
2578
  memcpy(&priv->sm_session.SKcfrm, &aeskeys[cs->aeskeylen * 0], cs->aeskeylen);
2579
  memcpy(&priv->sm_session.SKmac, &aeskeys[cs->aeskeylen * 1], cs->aeskeylen);
2580
  memcpy(&priv->sm_session.SKenc, &aeskeys[cs->aeskeylen * 2], cs->aeskeylen);
2581
  memcpy(&priv->sm_session.SKrmac, &aeskeys[cs->aeskeylen * 3], cs->aeskeylen);
2582
  sc_mem_clear(&aeskeys, sizeof(aeskeys));
2583
2584
  priv->sm_session.enc_counter[15] = 0x01;
2585
  priv->sm_session.resp_enc_counter[0] = 0x80;
2586
  priv->sm_session.resp_enc_counter[15] = 0x01;
2587
  /* C_MCV is zero */
2588
  /* R_MCV is zero */
2589
2590
  /*  Step H11 Zeroize Z (and kdf_in which has Z) */
2591
  if (Z && Zlen) {
2592
    sc_mem_clear(Z, Zlen);
2593
    free(Z);
2594
    Z = NULL;
2595
    Zlen = 0;
2596
  }
2597
  if (kdf_in && kdf_inlen) {
2598
    sc_mem_clear(kdf_in, kdf_inlen);
2599
    free(kdf_in);
2600
    kdf_in = NULL;
2601
    kdf_inlen = 0;
2602
  }
2603
2604
  /* Step H12 check AuthCryptogramting our version  */
2605
  /* Generate CMAC */
2606
2607
  {
2608
    u8 Check_AuthCryptogram[32];
2609
    size_t Check_Alen = 0;
2610
2611
    u8 MacData[200];
2612
    int MacDatalen;
2613
    memset(MacData, 0, sizeof(MacData));
2614
2615
    p = MacData;
2616
    memcpy(p, "\x4B\x43\x5f\x31\x5f\x56", 6);
2617
    p += 6;
2618
    memcpy(p, IDsicc, cs->IDsicclen);
2619
    p += cs->IDsicclen;
2620
    memcpy(p, IDsh, sizeof(IDsh));
2621
    p += sizeof(IDsh);
2622
2623
    memcpy(p, Qeh_OS, Qeh_OSlen);
2624
    p += Qeh_OSlen;
2625
    MacDatalen = (int)(p - MacData);
2626
2627
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2628
    if ((cmac_ctx = CMAC_CTX_new()) == NULL ||
2629
        CMAC_Init(cmac_ctx, priv->sm_session.SKcfrm, cs->aeskeylen, (*cs->cipher_cbc)(), NULL) != 1 ||
2630
        CMAC_Update(cmac_ctx, MacData, MacDatalen) != 1 ||
2631
        CMAC_Final(cmac_ctx, Check_AuthCryptogram, &Check_Alen) != 1) {
2632
      r = SC_ERROR_INTERNAL;
2633
      sc_log_openssl(card->ctx);
2634
      sc_log(card->ctx, "AES_CMAC failed %d", r);
2635
      goto err;
2636
    }
2637
#else
2638
    mac = EVP_MAC_fetch(PIV_LIBCTX, "cmac", NULL);
2639
    cmac_params[cmac_params_n++] = OSSL_PARAM_construct_utf8_string("cipher", cs->cipher_cbc_name, 0);
2640
2641
    cmac_params[cmac_params_n] = OSSL_PARAM_construct_end();
2642
    if (mac == NULL ||
2643
        (cmac_ctx = EVP_MAC_CTX_new(mac)) == NULL ||
2644
        !EVP_MAC_init(cmac_ctx, priv->sm_session.SKcfrm,
2645
            priv->sm_session.aes_size, cmac_params) ||
2646
        !EVP_MAC_update(cmac_ctx, MacData, MacDatalen) ||
2647
        !EVP_MAC_final(cmac_ctx, Check_AuthCryptogram, &Check_Alen, cs->AuthCryptogramlen)) {
2648
      sc_log_openssl(card->ctx);
2649
      r = SC_ERROR_INTERNAL;
2650
      sc_log(card->ctx, "AES_CMAC failed %d", r);
2651
      goto err;
2652
    }
2653
#endif
2654
2655
    if (0 == memcmp(AuthCryptogram, Check_AuthCryptogram, cs->AuthCryptogramlen)) {
2656
      sc_log(card->ctx, "AuthCryptogram compare");
2657
      r = 0;
2658
    } else {
2659
      sc_log(card->ctx, "AuthCryptogram compare failed");
2660
      r = SC_ERROR_SM_AUTHENTICATION_FAILED;
2661
      goto err;
2662
    }
2663
  }
2664
2665
  /* VCI only needed for contactless */
2666
  if (priv->init_flags & PIV_INIT_CONTACTLESS) {
2667
    /* Is pairing code required? */
2668
    if (!(priv->pin_policy & PIV_PP_VCI_WITHOUT_PC)) {
2669
      r = piv_send_vci_pairing_code(card, priv->pairing_code);
2670
      if (r < 0)
2671
        goto err;
2672
    }
2673
  }
2674
2675
  r = 0;
2676
  priv->sm_flags |= PIV_SM_FLAGS_SM_IS_ACTIVE;
2677
  card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
2678
2679
err:
2680
  priv->sm_flags &= ~PIV_SM_FLAGS_DEFER_OPEN;
2681
  if (r != 0) {
2682
    memset(&priv->sm_session, 0, sizeof(piv_sm_session_t));
2683
    sc_log_openssl(card->ctx); /* catch any not logged above */
2684
  }
2685
2686
  sc_unlock(card);
2687
2688
  free(sbuf);
2689
  free(kdf_in);
2690
  free(Z);
2691
2692
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2693
  EC_GROUP_free(Cicc_group);
2694
  EC_POINT_free(Cicc_point);
2695
  EC_KEY_free(Cicc_eckey);
2696
#endif
2697
2698
  EVP_PKEY_free(eph_pkey); /* in case not cleared in step H9 */
2699
  EVP_PKEY_CTX_free(eph_ctx);
2700
  EVP_PKEY_free(Cicc_pkey);
2701
  EVP_PKEY_CTX_free(Cicc_ctx);
2702
  EVP_PKEY_CTX_free(Z_ctx);
2703
  EVP_MD_CTX_free(hash_ctx);
2704
2705
#if OPENSSL_VERSION_NUMBER < 0x30000000L
2706
  CMAC_CTX_free(cmac_ctx);
2707
#else
2708
  EVP_MAC_CTX_free(cmac_ctx);
2709
  EVP_MAC_free(mac);
2710
  OPENSSL_free(Qehx);
2711
#endif
2712
2713
  LOG_FUNC_RETURN(card->ctx, r);
2714
}
2715
#endif /* ENABLE_PIV_SM */
2716
2717
/* Add the PIV-II operations */
2718
/* Should use our own keydata, actually should be common to all cards */
2719
/* RSA and EC are added. */
2720
2721
static int
2722
piv_generate_key(sc_card_t *card,
2723
    sc_cardctl_piv_genkey_info_t *keydata)
2724
0
{
2725
0
  int r;
2726
0
  u8 rbuf[4096];
2727
0
  u8 *p;
2728
0
  const u8 *tag;
2729
0
  u8 tagbuf[16];
2730
0
  u8 outdata[3]; /* we could also add tag 81 for exponent */
2731
0
  size_t taglen;
2732
0
  size_t out_len;
2733
0
  size_t in_len;
2734
0
  unsigned int cla_out, tag_out;
2735
2736
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2737
2738
0
  keydata->exponent = NULL;
2739
0
  keydata->exponent_len = 0;
2740
0
  keydata->pubkey = NULL;
2741
0
  keydata->pubkey_len = 0;
2742
0
  keydata->ecparam = NULL; /* will show size as we only support 2 curves */
2743
0
  keydata->ecparam_len = 0;
2744
0
  keydata->ecpoint = NULL;
2745
0
  keydata->ecpoint_len = 0;
2746
2747
0
  out_len = 3;
2748
0
  outdata[0] = 0x80;
2749
0
  outdata[1] = 0x01;
2750
0
  outdata[2] = keydata->key_algid;
2751
0
  switch (keydata->key_algid) {
2752
0
  case 0x05:
2753
0
    keydata->key_bits = 3072;
2754
0
    break;
2755
0
  case 0x06:
2756
0
    keydata->key_bits = 1024;
2757
0
    break;
2758
0
  case 0x07:
2759
0
    keydata->key_bits = 2048;
2760
0
    break;
2761
0
  case 0x16: /* Yubico 5.7 support for 4096 */
2762
0
    keydata->key_bits = 4096;
2763
0
    break;
2764
0
  case 0x11:
2765
0
    keydata->key_bits = 0;
2766
0
    keydata->ecparam = 0; /* we only support prime256v1 */
2767
0
    keydata->ecparam_len = 0;
2768
0
    break;
2769
0
  case 0x14:
2770
0
    keydata->key_bits = 0;
2771
0
    keydata->ecparam = 0; /* we only support secp384r1 */
2772
0
    keydata->ecparam_len = 0;
2773
0
    break;
2774
0
  case 0xE0: /* Yubico 5.7 support for EDDSA 25519 */
2775
0
  case 0xE1: /* Yubico 5.7 support for XEDDSA 25519 */
2776
0
    keydata->key_bits = 0;
2777
0
    keydata->ecparam = 0;
2778
0
    keydata->ecparam_len = 0;
2779
0
    break;
2780
0
  default:
2781
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
2782
0
  }
2783
2784
0
  p = tagbuf;
2785
2786
0
  r = sc_asn1_put_tag(0xAC, outdata, out_len, tagbuf, sizeof(tagbuf), &p);
2787
0
  if (r != SC_SUCCESS) {
2788
0
    sc_log(card->ctx, "Failed to encode ASN1 tag");
2789
0
    goto err;
2790
0
  }
2791
2792
0
  r = piv_general_io(card, 0x47, 0x00, keydata->key_num,
2793
0
      tagbuf, p - tagbuf, rbuf, sizeof rbuf);
2794
2795
0
  if (r >= 0) {
2796
0
    const u8 *cp;
2797
2798
0
    cp = rbuf;
2799
0
    in_len = r;
2800
2801
    /* expected tag is 0x7f49,returned as cla_out == 0x60 and tag_out = 0x1F49 */
2802
0
    r = sc_asn1_read_tag(&cp, in_len, &cla_out, &tag_out, &in_len);
2803
0
    if (r < 0 || cp == NULL || in_len == 0 || cla_out != 0x60 || tag_out != 0x1f49) {
2804
0
      r = SC_ERROR_ASN1_OBJECT_NOT_FOUND;
2805
0
    }
2806
0
    if (r != SC_SUCCESS) {
2807
0
      sc_log(card->ctx, "Tag buffer not found");
2808
0
      goto err;
2809
0
    }
2810
2811
    /* if RSA vs EC, ED25519 or X25519 */
2812
0
    if (keydata->key_bits > 0) {
2813
0
      tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x82, &taglen);
2814
0
      if (tag != NULL && taglen <= 4) {
2815
0
        keydata->exponent = malloc(taglen);
2816
0
        if (keydata->exponent == NULL)
2817
0
          LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2818
0
        keydata->exponent_len = taglen;
2819
0
        memcpy(keydata->exponent, tag, taglen);
2820
0
      } else {
2821
0
        sc_log(card->ctx, "Tag 0x82 not found");
2822
0
        r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
2823
0
        goto err;
2824
0
      }
2825
2826
0
      tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x81, &taglen);
2827
0
      if (tag != NULL && taglen > 0) {
2828
0
        keydata->pubkey = malloc(taglen);
2829
0
        if (keydata->pubkey == NULL) {
2830
0
          free(keydata->exponent);
2831
0
          LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2832
0
        }
2833
0
        keydata->pubkey_len = taglen;
2834
0
        memcpy(keydata->pubkey, tag, taglen);
2835
0
      } else {
2836
0
        sc_log(card->ctx, "Tag 0x81 not found");
2837
0
        r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
2838
0
        goto err;
2839
0
      }
2840
0
    } else { /* must be EC, ED25519 or X25519 */
2841
0
      tag = sc_asn1_find_tag(card->ctx, cp, in_len, 0x86, &taglen);
2842
0
      if (tag != NULL && taglen > 0) {
2843
0
        keydata->ecpoint = malloc(taglen);
2844
0
        if (keydata->ecpoint == NULL)
2845
0
          LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2846
0
        keydata->ecpoint_len = taglen;
2847
0
        memcpy(keydata->ecpoint, tag, taglen);
2848
0
      } else {
2849
0
        sc_log(card->ctx, "Tag 0x86 not found");
2850
0
        r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
2851
0
        goto err;
2852
0
      }
2853
0
    }
2854
2855
    /* Could add key to cache so could use engine to generate key,
2856
     * and sign req in single operation or write temporary selfsigned
2857
     * certificate with new public key
2858
     */
2859
0
    r = 0;
2860
0
  }
2861
2862
0
err:
2863
0
  if (r < 0) {
2864
0
    free(keydata->exponent);
2865
0
    keydata->exponent = NULL;
2866
0
    free(keydata->pubkey);
2867
0
    keydata->pubkey = NULL;
2868
0
    free(keydata->ecpoint);
2869
0
    keydata->ecpoint = NULL;
2870
0
  }
2871
2872
0
  LOG_FUNC_RETURN(card->ctx, r);
2873
0
}
2874
2875
static int
2876
piv_ai_map_find_by_id(sc_card_t *card, u8 id)
2877
31
{
2878
  /* piv_private_data_t * priv = PIV_DATA(card); */
2879
31
  int i;
2880
2881
189
  for (i = 0; ai_map[i].ai_id != 0; i++) {
2882
173
    if (ai_map[i].ai_id == id)
2883
15
      return i;
2884
173
  }
2885
16
  return -1;
2886
31
}
2887
2888
/* find the PIV AID on the card. If card->type already filled in,
2889
 * then look for specific AID only
2890
 */
2891
2892
static int
2893
piv_find_aid(sc_card_t *card)
2894
4.83k
{
2895
4.83k
  piv_private_data_t *priv = PIV_DATA(card);
2896
4.83k
  u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
2897
4.83k
  int r, i, j;
2898
4.83k
  const u8 *tag;
2899
4.83k
  size_t taglen;
2900
4.83k
  const u8 *nextac;
2901
4.83k
  const u8 *next80;
2902
4.83k
  const u8 *pix;
2903
4.83k
  size_t pixlen;
2904
4.83k
  const u8 *al_label;
2905
4.83k
  size_t al_labellen;
2906
4.83k
  const u8 *actag; /* Cipher Suite */
2907
4.83k
  size_t actaglen;
2908
4.83k
  const u8 *csai; /* Cipher Suite Algorithm Identifier */
2909
4.83k
  size_t csailen;
2910
4.83k
  size_t resplen = sizeof(rbuf);
2911
#ifdef ENABLE_PIV_SM
2912
  int found_csai = 0;
2913
#endif
2914
2915
4.83k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
2916
2917
  /* first  see if the default application will return a template
2918
   * that we know about.
2919
   */
2920
2921
4.83k
  r = iso7816_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, rbuf, &resplen);
2922
4.83k
  if (r > 0 && priv->aid_der.value && resplen == priv->aid_der.len && !memcmp(priv->aid_der.value, rbuf, resplen)) {
2923
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
2924
    /* no need to parse again, same as last time */
2925
0
  }
2926
4.83k
  if (r >= 0 && resplen > 2) {
2927
744
    tag = sc_asn1_find_tag(card->ctx, rbuf, resplen, 0x61, &taglen);
2928
744
    if (tag != NULL) {
2929
696
      priv->init_flags |= PIV_INIT_AID_PARSED;
2930
      /* look for 800-73-4 0xAC for Cipher Suite Algorithm Identifier Table 14 */
2931
      /* 800-73-4 only expects 1 0xAC tag len 6 with a 80 01 xx 06 01 00
2932
       * where xx is the SM csID either 27 or 2E.
2933
       * Some vendors may include entries for supported Algorithms even when
2934
       * not required. We will use these if possible
2935
       * Will look for multiple 0x80 with in 0xAC value too.
2936
       */
2937
696
      nextac = tag;
2938
800
      while ((actag = sc_asn1_find_tag(card->ctx, nextac, taglen - (nextac - tag),
2939
800
            0xAC, &actaglen)) != NULL) {
2940
104
        nextac = actag + actaglen;
2941
2942
104
        next80 = actag;
2943
220
        while ((csai = sc_asn1_find_tag(card->ctx, next80, actaglen - (next80 - actag),
2944
220
              0x80, &csailen)) != NULL) {
2945
116
          next80 = csai + csailen;
2946
116
          if (csailen == 1) {
2947
31
            sc_log(card->ctx, "0xAC 0x80 entry:0x%2.2x found", *csai);
2948
31
            j = piv_ai_map_find_by_id(card, *csai);
2949
31
            if (j >= 0) {
2950
15
              priv->alg_ids |= ai_map[j].ai_flag;
2951
15
              continue;
2952
15
            }
2953
#ifdef ENABLE_PIV_SM
2954
            /* check if id is NIST SM */
2955
            for (i = 0; i < PIV_CSS_SIZE; i++) {
2956
              if (*csai != css[i].id)
2957
                continue;
2958
              if (found_csai) {
2959
                sc_log(card->ctx, "found multiple csIDs, using first");
2960
              } else {
2961
                priv->cs = &css[i];
2962
                priv->csID = *csai;
2963
                found_csai++;
2964
                priv->init_flags |= PIV_INIT_AID_AC_SM;
2965
              }
2966
            }
2967
#endif /* ENABLE_PIV_SM */
2968
31
          }
2969
116
        }
2970
104
      }
2971
2972
      /* Last chance to distinguish card type based on Application Label '50' */
2973
696
      al_label = sc_asn1_find_tag(card->ctx, tag, taglen, 0x50, &al_labellen);
2974
696
      if (al_label != NULL) {
2975
16
        sc_log_hex(card->ctx, "Application Label", al_label, al_labellen);
2976
16
        if ((priv->al_label = malloc(al_labellen)) == NULL) {
2977
0
          LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2978
0
        }
2979
16
        memcpy(priv->al_label, al_label, al_labellen);
2980
16
        priv->al_labellen = (int)al_labellen;
2981
16
      }
2982
2983
696
      pix = sc_asn1_find_tag(card->ctx, tag, taglen, 0x4F, &pixlen);
2984
696
      if (pix != NULL) {
2985
668
        sc_log(card->ctx, "found PIX");
2986
2987
        /* early cards returned full AID, rather then just the pix */
2988
728
        for (i = 0; piv_aids[i].len_long != 0; i++) {
2989
699
          if ((pixlen >= piv_aids[i].len_long - 5 &&
2990
687
                  memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5) == 0) ||
2991
156
              ((pixlen >= piv_aids[i].len_short && memcmp(pix, piv_aids[i].value,
2992
639
                               piv_aids[i].len_short) == 0))) {
2993
639
            free(priv->aid_der.value); /* free previous value if any */
2994
639
            if ((priv->aid_der.value = malloc(resplen)) == NULL) {
2995
0
              LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
2996
0
            }
2997
639
            memcpy(priv->aid_der.value, rbuf, resplen);
2998
639
            priv->aid_der.len = resplen;
2999
639
            LOG_FUNC_RETURN(card->ctx, i);
3000
639
          }
3001
699
        }
3002
668
      }
3003
696
    }
3004
744
  }
3005
3006
4.19k
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NO_CARD_SUPPORT);
3007
4.19k
}
3008
3009
/*
3010
 * Read a DER encoded object from a file. Allocate and return the buf.
3011
 * Used to read the file defined in offCardCertURL from a cache.
3012
 * Also used for testing of History and Discovery objects from a file
3013
 * when testing with a card that does not support these new objects.
3014
 */
3015
static int
3016
piv_read_obj_from_file(sc_card_t *card, char *filename,
3017
    u8 **buf, size_t *buf_len)
3018
0
{
3019
0
  int r;
3020
0
  int r_tag;
3021
0
  int f = -1;
3022
0
  size_t len;
3023
0
  u8 tagbuf[16];
3024
0
  size_t rbuflen;
3025
0
  const u8 *body;
3026
0
  unsigned int cla_out, tag_out;
3027
0
  size_t bodylen;
3028
3029
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
3030
3031
0
  *buf = NULL;
3032
0
  *buf_len = 0;
3033
0
  f = open(filename, O_RDONLY);
3034
0
  if (f < 0) {
3035
0
    sc_log(card->ctx, "Unable to load PIV off card file: \"%s\"", filename);
3036
0
    r = SC_ERROR_FILE_NOT_FOUND;
3037
0
    goto err;
3038
0
  }
3039
0
  len = read(f, tagbuf, sizeof(tagbuf)); /* get tag and length */
3040
0
  if (len < 2 || len > sizeof(tagbuf)) {
3041
0
    sc_log(card->ctx, "Problem with \"%s\"", filename);
3042
0
    r = SC_ERROR_DATA_OBJECT_NOT_FOUND;
3043
0
    goto err;
3044
0
  }
3045
0
  body = tagbuf;
3046
  /* accept any tag for now, just get length */
3047
0
  r_tag = sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen);
3048
0
  if ((r_tag != SC_SUCCESS && r_tag != SC_ERROR_ASN1_END_OF_CONTENTS) ||
3049
0
      body == NULL) {
3050
0
    sc_log(card->ctx, "DER problem");
3051
0
    r = SC_ERROR_FILE_NOT_FOUND;
3052
0
    goto err;
3053
0
  }
3054
0
  rbuflen = body - tagbuf + bodylen;
3055
0
  *buf = malloc(rbuflen);
3056
0
  if (!*buf) {
3057
0
    r = SC_ERROR_OUT_OF_MEMORY;
3058
0
    goto err;
3059
0
  }
3060
0
  memcpy(*buf, tagbuf, MIN(len, rbuflen)); /* copy first or only part */
3061
  /* read rest of file */
3062
0
  if (rbuflen > len + sizeof(tagbuf)) {
3063
0
    len = read(f, *buf + sizeof(tagbuf), rbuflen - sizeof(tagbuf)); /* read rest */
3064
0
    if (len != rbuflen - sizeof(tagbuf)) {
3065
0
      r = SC_ERROR_INVALID_ASN1_OBJECT;
3066
0
      free(*buf);
3067
0
      *buf = NULL;
3068
0
      goto err;
3069
0
    }
3070
0
  }
3071
0
  r = (int)rbuflen;
3072
0
  *buf_len = rbuflen;
3073
0
err:
3074
0
  if (f >= 0)
3075
0
    close(f);
3076
0
  LOG_FUNC_RETURN(card->ctx, r);
3077
0
}
3078
3079
/* the tag is the PIV_OBJ_*  */
3080
static int
3081
piv_get_data(sc_card_t *card, int enumtag, u8 **buf, size_t *buf_len)
3082
6.63k
{
3083
6.63k
  piv_private_data_t *priv = PIV_DATA(card);
3084
6.63k
  u8 *p;
3085
6.63k
  u8 *tbuf;
3086
6.63k
  int r = 0;
3087
6.63k
  u8 tagbuf[8];
3088
6.63k
  size_t tag_len;
3089
6.63k
  int alloc_buf = 0;
3090
3091
6.63k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
3092
3093
6.63k
  sc_log(card->ctx, "#%d, %s", enumtag, piv_objects[enumtag].name);
3094
3095
6.63k
  r = sc_lock(card); /* do check len and get data in same transaction */
3096
6.63k
  if (r != SC_SUCCESS) {
3097
0
    sc_log(card->ctx, "sc_lock failed");
3098
0
    return r;
3099
0
  }
3100
3101
6.63k
  tag_len = piv_objects[enumtag].tag_len;
3102
3103
6.63k
  p = tagbuf;
3104
6.63k
  r = sc_asn1_put_tag(0x5c, piv_objects[enumtag].tag_value, tag_len, tagbuf, sizeof(tagbuf), &p);
3105
6.63k
  if (r != SC_SUCCESS) {
3106
0
    sc_log(card->ctx, "Failed to encode ASN1 tag");
3107
0
    goto err;
3108
0
  }
3109
3110
6.63k
  if (*buf_len == 1 && *buf == NULL) {
3111
6.63k
    *buf_len = priv->max_object_size; /* will allocate below */
3112
6.63k
    alloc_buf = 1;
3113
6.63k
  }
3114
3115
6.63k
  sc_log(card->ctx,
3116
6.63k
      "buffer for #%d *buf=0x%p len=%" SC_FORMAT_LEN_SIZE_T "u",
3117
6.63k
      enumtag, *buf, *buf_len);
3118
6.63k
  if (*buf == NULL && *buf_len > 0) {
3119
6.63k
    if (*buf_len > MAX_FILE_SIZE) {
3120
0
      r = SC_ERROR_INTERNAL;
3121
0
      goto err;
3122
0
    }
3123
6.63k
    *buf = malloc(*buf_len);
3124
6.63k
    if (*buf == NULL) {
3125
0
      r = SC_ERROR_OUT_OF_MEMORY;
3126
0
      goto err;
3127
0
    }
3128
6.63k
  }
3129
3130
#ifdef ENABLE_PIV_SM
3131
  /*
3132
   * Over contact reader, OK to read non sensitive object in clear even when SM is active
3133
   * but only if using default policy and we are not in reader_lock_obtained
3134
   * Discovery object will use SM from reader_lock_obtained to catch if SM is still valid
3135
   * i.e. no interference from other applications
3136
   */
3137
  sc_log(card->ctx, "enumtag:%d sm_ctx.sm_mode:%d piv_objects[enumtag].flags:0x%8.8x sm_flags:0x%8.8lx it_flags:0x%8.8x",
3138
      enumtag, card->sm_ctx.sm_mode, piv_objects[enumtag].flags, priv->sm_flags, priv->init_flags);
3139
  if (priv->sm_flags & PIV_SM_FLAGS_SM_IS_ACTIVE &&
3140
      enumtag != PIV_OBJ_DISCOVERY &&
3141
      card->sm_ctx.sm_mode == SM_MODE_TRANSMIT &&
3142
      !(piv_objects[enumtag].flags & PIV_OBJECT_NEEDS_PIN) &&
3143
      !(priv->sm_flags & (PIV_SM_FLAGS_NEVER | PIV_SM_FLAGS_ALWAYS)) &&
3144
      !(priv->init_flags & (PIV_INIT_CONTACTLESS | PIV_INIT_IN_READER_LOCK_OBTAINED))) {
3145
    sc_log(card->ctx, "Set PIV_SM_GET_DATA_IN_CLEAR");
3146
    priv->sm_flags |= PIV_SM_GET_DATA_IN_CLEAR;
3147
  }
3148
3149
#endif /* ENABLE_PIV_SM */
3150
6.63k
  r = piv_general_io(card, 0xCB, 0x3F, 0xFF, tagbuf, p - tagbuf, *buf, *buf_len);
3151
6.63k
  if (r > 0) {
3152
1.17k
    int r_tag;
3153
1.17k
    unsigned int cla_out, tag_out;
3154
1.17k
    size_t bodylen = 0;
3155
1.17k
    const u8 *body = *buf;
3156
1.17k
    r_tag = sc_asn1_read_tag(&body, r, &cla_out, &tag_out, &bodylen);
3157
1.17k
    if (r_tag != SC_SUCCESS || body == NULL ||
3158
1.00k
        ((cla_out << 24 | tag_out) != piv_objects[enumtag].resp_tag)) {
3159
278
      sc_log(card->ctx, "invalid tag or length r_tag:%d body:%p", r_tag, body);
3160
278
      r = SC_ERROR_FILE_NOT_FOUND;
3161
278
      goto err;
3162
278
    }
3163
896
    *buf_len = (body - *buf) + bodylen;
3164
5.46k
  } else if (r == 0) {
3165
101
    r = SC_ERROR_FILE_NOT_FOUND;
3166
101
    goto err;
3167
5.36k
  } else {
3168
5.36k
    goto err;
3169
5.36k
  }
3170
3171
896
  if (alloc_buf && *buf) {
3172
896
    tbuf = malloc(r);
3173
896
    if (tbuf == NULL) {
3174
0
      r = SC_ERROR_OUT_OF_MEMORY;
3175
0
      goto err;
3176
0
    }
3177
896
    memcpy(tbuf, *buf, r);
3178
896
    free(*buf);
3179
896
    alloc_buf = 0;
3180
896
    *buf = tbuf;
3181
896
  }
3182
3183
6.63k
err:
3184
6.63k
  if (alloc_buf) {
3185
5.74k
    free(*buf);
3186
5.74k
    *buf = NULL;
3187
5.74k
  }
3188
6.63k
  sc_unlock(card);
3189
6.63k
  LOG_FUNC_RETURN(card->ctx, r);
3190
6.63k
}
3191
3192
static int
3193
piv_get_cached_data(sc_card_t *card, int enumtag, u8 **buf, size_t *buf_len)
3194
7.00k
{
3195
3196
7.00k
  piv_private_data_t *priv = PIV_DATA(card);
3197
7.00k
  int r;
3198
7.00k
  u8 *rbuf = NULL;
3199
7.00k
  size_t rbuflen;
3200
3201
7.00k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
3202
3203
7.00k
  if (enumtag < 0 || enumtag >= PIV_OBJ_LAST_ENUM)
3204
0
    return SC_ERROR_INTERNAL;
3205
3206
7.00k
  sc_log(card->ctx, "#%d, %s", enumtag, piv_objects[enumtag].name);
3207
3208
  /* see if we have it cached */
3209
7.00k
  if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_VALID) {
3210
3211
408
    sc_log(card->ctx,
3212
408
        "found #%d %p:%" SC_FORMAT_LEN_SIZE_T "u %p:%" SC_FORMAT_LEN_SIZE_T "u",
3213
408
        enumtag,
3214
408
        priv->obj_cache[enumtag].obj_data,
3215
408
        priv->obj_cache[enumtag].obj_len,
3216
408
        priv->obj_cache[enumtag].internal_obj_data,
3217
408
        priv->obj_cache[enumtag].internal_obj_len);
3218
3219
408
    if (priv->obj_cache[enumtag].obj_len == 0) {
3220
0
      r = SC_ERROR_FILE_NOT_FOUND;
3221
0
      sc_log(card->ctx, "#%d found but len=0", enumtag);
3222
0
      goto err;
3223
0
    }
3224
408
    *buf = priv->obj_cache[enumtag].obj_data;
3225
408
    *buf_len = priv->obj_cache[enumtag].obj_len;
3226
408
    r = (int)*buf_len;
3227
408
    goto ok;
3228
408
  }
3229
3230
  /*
3231
   * If we know it can not be on the card  i.e. History object
3232
   * has been read, and we know what other certs may or
3233
   * may not be on the card. We can avoid extra overhead
3234
   * Also used if object on card was not parsable
3235
   */
3236
3237
6.59k
  if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_NOT_PRESENT) {
3238
0
    sc_log(card->ctx, "no_obj #%d", enumtag);
3239
0
    r = SC_ERROR_FILE_NOT_FOUND;
3240
0
    goto err;
3241
0
  }
3242
3243
  /* Not cached, try to get it, piv_get_data will allocate a buf */
3244
6.59k
  sc_log(card->ctx, "get #%d", enumtag);
3245
6.59k
  rbuflen = 1;
3246
6.59k
  r = piv_get_data(card, enumtag, &rbuf, &rbuflen);
3247
6.59k
  if (r > 0) {
3248
868
    priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_VALID;
3249
868
    priv->obj_cache[enumtag].obj_len = r;
3250
868
    priv->obj_cache[enumtag].obj_data = rbuf;
3251
868
    *buf = rbuf;
3252
868
    *buf_len = r;
3253
3254
868
    sc_log(card->ctx,
3255
868
        "added #%d  %p:%" SC_FORMAT_LEN_SIZE_T "u %p:%" SC_FORMAT_LEN_SIZE_T "u",
3256
868
        enumtag,
3257
868
        priv->obj_cache[enumtag].obj_data,
3258
868
        priv->obj_cache[enumtag].obj_len,
3259
868
        priv->obj_cache[enumtag].internal_obj_data,
3260
868
        priv->obj_cache[enumtag].internal_obj_len);
3261
3262
5.72k
  } else {
3263
5.72k
    free(rbuf);
3264
5.72k
    if (r == 0 || r == SC_ERROR_FILE_NOT_FOUND) {
3265
432
      r = SC_ERROR_FILE_NOT_FOUND;
3266
432
      priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_VALID;
3267
432
      priv->obj_cache[enumtag].obj_len = 0;
3268
5.29k
    } else {
3269
5.29k
      goto err;
3270
5.29k
    }
3271
5.72k
  }
3272
1.70k
ok:
3273
3274
7.00k
err:
3275
7.00k
  LOG_FUNC_RETURN(card->ctx, r);
3276
7.00k
}
3277
3278
static int
3279
piv_cache_internal_data(sc_card_t *card, int enumtag)
3280
928
{
3281
928
  piv_private_data_t *priv = PIV_DATA(card);
3282
928
  const u8 *tag;
3283
928
  const u8 *body;
3284
928
  size_t taglen;
3285
928
  size_t bodylen;
3286
928
  int compressed = 0;
3287
928
  int r = SC_SUCCESS;
3288
#ifdef ENABLE_PIV_SM
3289
  u8 *cvc_start = NULL;
3290
  size_t cvc_len = 0;
3291
#endif
3292
3293
  /* if already cached */
3294
928
  if (priv->obj_cache[enumtag].internal_obj_data && priv->obj_cache[enumtag].internal_obj_len) {
3295
408
    sc_log(card->ctx,
3296
408
        "#%d found internal %p:%" SC_FORMAT_LEN_SIZE_T "u",
3297
408
        enumtag,
3298
408
        priv->obj_cache[enumtag].internal_obj_data,
3299
408
        priv->obj_cache[enumtag].internal_obj_len);
3300
408
    LOG_FUNC_RETURN(card->ctx, r);
3301
408
  }
3302
3303
520
  body = sc_asn1_find_tag(card->ctx,
3304
520
      priv->obj_cache[enumtag].obj_data,
3305
520
      priv->obj_cache[enumtag].obj_len,
3306
520
      0x53, &bodylen);
3307
3308
520
  if (body == NULL || priv->obj_cache[enumtag].obj_data[0] != 0x53)
3309
520
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
3310
3311
  /* get the certificate out */
3312
520
  if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_CERT) {
3313
3314
520
    tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x71, &taglen);
3315
    /* 800-72-1 not clear if this is 80 or 01 Sent comment to NIST for 800-72-2 */
3316
    /* 800-73-3 says it is 01, keep dual test so old cards still work */
3317
520
    if (tag && taglen > 0 && (((*tag) & 0x80) || ((*tag) & 0x01)))
3318
18
      compressed = 1;
3319
3320
#ifdef ENABLE_PIV_SM
3321
    cvc_start = (u8 *)tag + taglen; /* save for later as cvs (if present) follows  0x71 */
3322
#endif
3323
3324
520
    tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x70, &taglen);
3325
520
    if (tag == NULL)
3326
520
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
3327
3328
419
    if (taglen == 0)
3329
419
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND);
3330
3331
408
    if (compressed) {
3332
6
      priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_COMPRESSED;
3333
6
    }
3334
    /* internal certificate remains compressed */
3335
408
    if (!(priv->obj_cache[enumtag].internal_obj_data = malloc(taglen)))
3336
408
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
3337
3338
408
    memcpy(priv->obj_cache[enumtag].internal_obj_data, tag, taglen);
3339
408
    priv->obj_cache[enumtag].internal_obj_len = taglen;
3340
3341
#ifdef ENABLE_PIV_SM
3342
    /* PIV_OBJ_SM_CERT_SIGNER  CERT OBJECT may also have a intermediate CVC */
3343
    if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_CVC) {
3344
      /* cvc if present should be at cvc_start.
3345
       * find the tag(T) and get value(V) and len(L) from TLV.
3346
       * Could reconstruct ASN1 of (T)(L) stating location from length and known tag.
3347
       * as the size of (L) depends on the length of value
3348
       */
3349
      if ((tag = sc_asn1_find_tag(card->ctx, body, bodylen, 0x7F21, &taglen)) != NULL &&
3350
          cvc_start &&
3351
          cvc_start < tag &&
3352
          cvc_start[0] == 0x7f && cvc_start[1] == 0x21) {
3353
        cvc_len = tag - cvc_start + taglen;
3354
        /* decode the intermediate CVC */
3355
        r = piv_decode_cvc(card, &cvc_start, &cvc_len, &priv->sm_in_cvc);
3356
        if (r < 0) {
3357
          sc_log(card->ctx, "unable to parse intermediate CVC: %d skipping", r);
3358
        }
3359
        priv->sm_flags |= PIV_SM_FLAGS_SM_IN_CVC_PRESENT;
3360
      }
3361
    }
3362
#endif /* ENABLE_PIV_SM */
3363
3364
    /* convert pub key to internal */
3365
408
  } else if (piv_objects[enumtag].flags & PIV_OBJECT_TYPE_PUBKEY) {
3366
0
    tag = sc_asn1_find_tag(card->ctx, body, bodylen, *body, &taglen);
3367
0
    if (tag == NULL)
3368
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
3369
3370
0
    if (taglen == 0)
3371
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND);
3372
3373
0
    if (!(priv->obj_cache[enumtag].internal_obj_data = malloc(taglen)))
3374
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
3375
3376
0
    memcpy(priv->obj_cache[enumtag].internal_obj_data, tag, taglen);
3377
0
    priv->obj_cache[enumtag].internal_obj_len = taglen;
3378
0
  } else {
3379
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
3380
0
  }
3381
3382
408
  sc_log(card->ctx, "added #%d internal %p:%" SC_FORMAT_LEN_SIZE_T "u",
3383
408
      enumtag,
3384
408
      priv->obj_cache[enumtag].internal_obj_data,
3385
408
      priv->obj_cache[enumtag].internal_obj_len);
3386
3387
408
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
3388
408
}
3389
3390
/*
3391
 * Callers of this may be expecting a certificate,
3392
 * select file will have saved the object type for us
3393
 * as well as set that we want the cert from the object.
3394
 */
3395
static int
3396
piv_read_binary(sc_card_t *card, unsigned int idx, unsigned char *buf, size_t count, unsigned long *flags)
3397
1.47k
{
3398
1.47k
  piv_private_data_t *priv = PIV_DATA(card);
3399
1.47k
  int enumtag;
3400
1.47k
  int r;
3401
1.47k
  u8 *rbuf = NULL;
3402
1.47k
  size_t rbuflen = 0;
3403
1.47k
  const u8 *body;
3404
1.47k
  size_t bodylen;
3405
3406
1.47k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
3407
1.47k
  if (priv->selected_obj < 0)
3408
1.47k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
3409
1.47k
  enumtag = piv_objects[priv->selected_obj].enumtag;
3410
3411
1.47k
  if (priv->rwb_state == -1) {
3412
408
    r = piv_get_cached_data(card, enumtag, &rbuf, &rbuflen);
3413
3414
408
    if (r >= 0) {
3415
      /* an object with no data will be considered not found */
3416
      /* Discovery tag = 0x73, all others are 0x53 */
3417
408
      if (!rbuf || rbuf[0] == 0x00 || ((rbuf[0] & 0xDF) == 0x53 && rbuf[1] == 0x00)) {
3418
0
        r = SC_ERROR_FILE_NOT_FOUND;
3419
0
        goto err;
3420
0
      }
3421
3422
408
      body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, rbuf[0], &bodylen);
3423
408
      if (body == NULL) {
3424
        /* if missing, assume its the body */
3425
        /* DEE bug in the beta card */
3426
0
        sc_log(card->ctx, " ***** tag 0x53 MISSING");
3427
0
        r = SC_ERROR_INVALID_DATA;
3428
0
        goto err;
3429
0
      }
3430
408
      if (bodylen > body - rbuf + rbuflen) {
3431
0
        sc_log(card->ctx,
3432
0
            " ***** tag length > then data: %" SC_FORMAT_LEN_SIZE_T "u>%" SC_FORMAT_LEN_PTRDIFF_T "u+%" SC_FORMAT_LEN_SIZE_T "u",
3433
0
            bodylen, body - rbuf, rbuflen);
3434
0
        r = SC_ERROR_INVALID_DATA;
3435
0
        goto err;
3436
0
      }
3437
      /* if cached obj has internal interesting data (cert or pub key) */
3438
408
      if (priv->return_only_cert || piv_objects[enumtag].flags & PIV_OBJECT_TYPE_PUBKEY) {
3439
408
        r = piv_cache_internal_data(card, enumtag);
3440
408
        if (r < 0)
3441
0
          goto err;
3442
408
      }
3443
408
    }
3444
408
    priv->rwb_state = 0;
3445
408
  }
3446
3447
1.47k
  if (priv->return_only_cert || piv_objects[enumtag].flags & PIV_OBJECT_TYPE_PUBKEY) {
3448
1.47k
    rbuf = priv->obj_cache[enumtag].internal_obj_data;
3449
1.47k
    rbuflen = priv->obj_cache[enumtag].internal_obj_len;
3450
1.47k
    if ((priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_COMPRESSED) && flags) {
3451
27
      *flags |= SC_FILE_FLAG_COMPRESSED_AUTO;
3452
27
    }
3453
1.47k
  } else {
3454
0
    rbuf = priv->obj_cache[enumtag].obj_data;
3455
0
    rbuflen = priv->obj_cache[enumtag].obj_len;
3456
0
  }
3457
  /* rbuf rbuflen has pointer and length to cached data */
3458
3459
1.47k
  if (rbuflen < idx + count)
3460
0
    count = rbuflen - idx;
3461
1.47k
  if (count <= 0) {
3462
0
    r = 0;
3463
0
    priv->rwb_state = 1;
3464
1.47k
  } else {
3465
1.47k
    memcpy(buf, rbuf + idx, count);
3466
1.47k
    r = (int)count;
3467
1.47k
  }
3468
3469
1.47k
err:
3470
1.47k
  LOG_FUNC_RETURN(card->ctx, r);
3471
1.47k
}
3472
3473
/*
3474
 * the tag is the PIV_OBJ_*
3475
 * The buf should have the 0x53 tag+len+tags and data
3476
 */
3477
3478
static int
3479
piv_put_data(sc_card_t *card, int tag, const u8 *buf, size_t buf_len)
3480
0
{
3481
0
  int r;
3482
0
  u8 *sbuf;
3483
0
  size_t sbuflen;
3484
0
  u8 *p;
3485
0
  size_t tag_len;
3486
3487
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
3488
3489
0
  tag_len = piv_objects[tag].tag_len;
3490
0
  r = sc_asn1_put_tag(0x5c, piv_objects[tag].tag_value, tag_len, NULL, 0, NULL);
3491
0
  if (r <= 0) {
3492
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
3493
0
  }
3494
0
  sbuflen = r + buf_len;
3495
0
  if (!(sbuf = malloc(sbuflen))) {
3496
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
3497
0
  }
3498
3499
0
  p = sbuf;
3500
0
  r = sc_asn1_put_tag(0x5c, piv_objects[tag].tag_value, tag_len, sbuf, sbuflen, &p);
3501
0
  if (r != SC_SUCCESS) {
3502
0
    LOG_FUNC_RETURN(card->ctx, r);
3503
0
  }
3504
3505
  /* This is safe as we calculated the size of buffer above */
3506
0
  memcpy(p, buf, buf_len);
3507
0
  p += buf_len;
3508
3509
0
  r = piv_general_io(card, 0xDB, 0x3F, 0xFF, sbuf, p - sbuf, NULL, 0);
3510
3511
0
  if (sbuf)
3512
0
    free(sbuf);
3513
0
  LOG_FUNC_RETURN(card->ctx, r);
3514
0
}
3515
3516
static int
3517
piv_write_certificate(sc_card_t *card, const u8 *buf, size_t count, unsigned long flags)
3518
0
{
3519
0
  piv_private_data_t *priv = PIV_DATA(card);
3520
0
  int enumtag, tmplen, tmplen2, tmplen3;
3521
0
  int r = SC_SUCCESS;
3522
0
  u8 *sbuf = NULL;
3523
0
  u8 *p;
3524
0
  size_t sbuflen;
3525
0
  size_t taglen;
3526
3527
0
  if ((tmplen = sc_asn1_put_tag(0x70, buf, count, NULL, 0, NULL)) <= 0 ||
3528
0
      (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 ||
3529
0
      (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) {
3530
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
3531
0
  }
3532
3533
0
  taglen = tmplen + tmplen2 + tmplen3;
3534
0
  tmplen = sc_asn1_put_tag(0x53, NULL, taglen, NULL, 0, NULL);
3535
0
  if (tmplen <= 0) {
3536
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
3537
0
  }
3538
3539
0
  sbuflen = tmplen;
3540
0
  sbuf = malloc(sbuflen);
3541
0
  if (sbuf == NULL)
3542
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
3543
0
  p = sbuf;
3544
0
  if ((r = sc_asn1_put_tag(0x53, NULL, taglen, sbuf, sbuflen, &p)) != SC_SUCCESS ||
3545
0
      (r = sc_asn1_put_tag(0x70, buf, count, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS ||
3546
0
      (r = sc_asn1_put_tag(0x71, NULL, 1, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) {
3547
0
    goto out;
3548
0
  }
3549
  /* Use 01 as per NIST 800-73-3 */
3550
0
  *p++ = (flags) ? 0x01 : 0x00; /* certinfo, i.e. gzipped? */
3551
0
  r = sc_asn1_put_tag(0xFE, NULL, 0, p, sbuflen - (p - sbuf), &p);
3552
0
  if (r != SC_SUCCESS) {
3553
0
    goto out;
3554
0
  }
3555
3556
0
  enumtag = piv_objects[priv->selected_obj].enumtag;
3557
0
  r = piv_put_data(card, enumtag, sbuf, sbuflen);
3558
3559
0
out:
3560
0
  free(sbuf);
3561
0
  LOG_FUNC_RETURN(card->ctx, r);
3562
0
}
3563
3564
/*
3565
 * For certs we need to add the 0x53 tag and other specific tags,
3566
 * and call the piv_put_data
3567
 * Note: the select file will have saved the object type for us
3568
 * Write is used by piv-tool, so we will use flags:
3569
 *  length << 8 | 8bits:
3570
 * object            xxxx0000
3571
 * uncompressed cert xxx00001
3572
 * compressed cert   xxx10001
3573
 * pubkey            xxxx0010
3574
 *
3575
 * to indicate we are writing a cert and if is compressed
3576
 * or if we are writing a pubkey in to the cache.
3577
 * if its not a cert or pubkey its an object.
3578
 *
3579
 * Therefore when idx=0, we will get the length of the object
3580
 * and allocate a buffer, so we can support partial writes.
3581
 * When the last chuck of the data is sent, we will write it.
3582
 */
3583
3584
static int
3585
piv_write_binary(sc_card_t *card, unsigned int idx,
3586
    const u8 *buf, size_t count, unsigned long flags)
3587
0
{
3588
0
  piv_private_data_t *priv = PIV_DATA(card);
3589
0
  int r;
3590
0
  int enumtag;
3591
3592
0
  LOG_FUNC_CALLED(card->ctx);
3593
3594
0
  if (priv->selected_obj < 0)
3595
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
3596
3597
0
  enumtag = piv_objects[priv->selected_obj].enumtag;
3598
3599
0
  if (priv->rwb_state == 1) /* trying to write at end */
3600
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
3601
3602
0
  if (priv->rwb_state == -1) {
3603
3604
    /* if  cached, remove old entry */
3605
0
    if (priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_VALID) {
3606
0
      piv_obj_cache_free_entry(card, enumtag, 0);
3607
0
    }
3608
3609
0
    if (idx != 0)
3610
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NO_CARD_SUPPORT);
3611
3612
0
    priv->w_buf_len = flags >> 8;
3613
0
    if (priv->w_buf_len == 0)
3614
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
3615
3616
0
    priv->w_buf = malloc(priv->w_buf_len);
3617
0
    priv->rwb_state = 0;
3618
0
  }
3619
3620
  /* on each pass make sure we have w_buf */
3621
0
  if (priv->w_buf == NULL)
3622
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
3623
3624
0
  if (idx + count > priv->w_buf_len)
3625
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_VALID);
3626
3627
0
  memcpy(priv->w_buf + idx, buf, count); /* copy one chunk */
3628
3629
  /* if this was not the last chunk, return to get rest */
3630
0
  if (idx + count < priv->w_buf_len)
3631
0
    LOG_FUNC_RETURN(card->ctx, (int)count);
3632
3633
0
  priv->rwb_state = 1; /* at end of object */
3634
3635
0
  switch (flags & 0x0f) {
3636
0
  case 1:
3637
0
    r = piv_write_certificate(card, priv->w_buf, priv->w_buf_len, flags & 0x10);
3638
0
    break;
3639
0
  case 2: /* pubkey to be added to cache, it should have 0x53 and 0x99 tags. */
3640
0
    r = (int)priv->w_buf_len;
3641
0
    break;
3642
0
  default:
3643
0
    r = piv_put_data(card, enumtag, priv->w_buf, priv->w_buf_len);
3644
0
    break;
3645
0
  }
3646
  /* if it worked, will cache it */
3647
0
  if (r >= 0 && priv->w_buf) {
3648
0
    priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_VALID;
3649
0
    priv->obj_cache[enumtag].obj_data = priv->w_buf;
3650
0
    priv->obj_cache[enumtag].obj_len = priv->w_buf_len;
3651
0
  } else {
3652
0
    if (priv->w_buf)
3653
0
      free(priv->w_buf);
3654
0
  }
3655
0
  priv->w_buf = NULL;
3656
0
  priv->w_buf_len = 0;
3657
0
  LOG_FUNC_RETURN(card->ctx, (r < 0) ? r : (int)count);
3658
0
}
3659
3660
/*
3661
 * Card initialization is NOT standard.
3662
 * Some cards use mutual or external authentication using 3des or aes key. We
3663
 * will read in the key from a file either binary or hex encoded.
3664
 * This is only needed during initialization/personalization of the card
3665
 */
3666
3667
#ifdef ENABLE_OPENSSL
3668
static EVP_CIPHER *
3669
get_cipher_for_algo(sc_card_t *card, int alg_id)
3670
0
{
3671
0
  const char *algo;
3672
0
  switch (alg_id) {
3673
0
  case 0x0:
3674
0
  case 0x1: /* 2TDES */
3675
0
  case 0x3:
3676
0
    algo = "DES-EDE3-ECB";
3677
0
    break;
3678
0
  case 0x8:
3679
0
    algo = "AES-128-ECB";
3680
0
    break;
3681
0
  case 0xA:
3682
0
    algo = "AES-192-ECB";
3683
0
    break;
3684
0
  case 0xC:
3685
0
    algo = "AES-256-ECB";
3686
0
    break;
3687
0
  default:
3688
0
    return NULL;
3689
0
  }
3690
0
  return sc_evp_cipher(card->ctx, algo);
3691
0
}
3692
3693
static int
3694
get_keylen(unsigned int alg_id, size_t *size)
3695
0
{
3696
0
  switch (alg_id) {
3697
0
  case 0x01:
3698
0
    *size = 192 / 8; /* 2TDES still has 3 single des keys  phase out by 12/31/2010 */
3699
0
    break;
3700
0
  case 0x00:
3701
0
  case 0x03:
3702
0
    *size = 192 / 8;
3703
0
    break;
3704
0
  case 0x08:
3705
0
    *size = 128 / 8;
3706
0
    break;
3707
0
  case 0x0A:
3708
0
    *size = 192 / 8;
3709
0
    break;
3710
0
  case 0x0C:
3711
0
    *size = 256 / 8;
3712
0
    break;
3713
0
  default:
3714
0
    return SC_ERROR_INVALID_ARGUMENTS;
3715
0
  }
3716
0
  return SC_SUCCESS;
3717
0
}
3718
3719
static int
3720
piv_get_key(sc_card_t *card, unsigned int alg_id, u8 **key, size_t *len)
3721
0
{
3722
3723
0
  int r;
3724
0
  size_t fsize;
3725
0
  FILE *f = NULL;
3726
0
  char *keyfilename = NULL;
3727
0
  size_t expected_keylen;
3728
0
  size_t keylen, readlen;
3729
0
  u8 *keybuf = NULL;
3730
0
  u8 *tkey = NULL;
3731
3732
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
3733
3734
0
  keyfilename = (char *)getenv("PIV_EXT_AUTH_KEY");
3735
3736
0
  if (keyfilename == NULL) {
3737
0
    sc_log(card->ctx,
3738
0
        "Unable to get PIV_EXT_AUTH_KEY=(null) for general_external_authenticate");
3739
0
    r = SC_ERROR_FILE_NOT_FOUND;
3740
0
    goto err;
3741
0
  }
3742
3743
0
  r = get_keylen(alg_id, &expected_keylen);
3744
0
  if (r) {
3745
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for:  %02x", alg_id);
3746
0
    r = SC_ERROR_INVALID_ARGUMENTS;
3747
0
    goto err;
3748
0
  }
3749
3750
0
  f = fopen(keyfilename, "rb");
3751
0
  if (!f) {
3752
0
    sc_log(card->ctx, " Unable to load key from file\n");
3753
0
    r = SC_ERROR_FILE_NOT_FOUND;
3754
0
    goto err;
3755
0
  }
3756
3757
0
  if (0 > fseek(f, 0L, SEEK_END))
3758
0
    r = SC_ERROR_INTERNAL;
3759
0
  fsize = ftell(f);
3760
0
  if (0 > (long)fsize)
3761
0
    r = SC_ERROR_INTERNAL;
3762
0
  if (0 > fseek(f, 0L, SEEK_SET))
3763
0
    r = SC_ERROR_INTERNAL;
3764
0
  if (r) {
3765
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not read %s\n", keyfilename);
3766
0
    goto err;
3767
0
  }
3768
3769
0
  keybuf = malloc(fsize + 1); /* if not binary, need null to make it a string */
3770
0
  if (!keybuf) {
3771
0
    sc_log(card->ctx, " Unable to allocate key memory");
3772
0
    r = SC_ERROR_OUT_OF_MEMORY;
3773
0
    goto err;
3774
0
  }
3775
0
  keybuf[fsize] = 0x00; /* in case it is text need null */
3776
3777
0
  if ((readlen = fread(keybuf, 1, fsize, f)) != fsize) {
3778
0
    sc_log(card->ctx, " Unable to read key\n");
3779
0
    r = SC_ERROR_WRONG_LENGTH;
3780
0
    goto err;
3781
0
  }
3782
0
  keybuf[readlen] = '\0';
3783
3784
0
  tkey = malloc(expected_keylen);
3785
0
  if (!tkey) {
3786
0
    sc_log(card->ctx, " Unable to allocate key memory");
3787
0
    r = SC_ERROR_OUT_OF_MEMORY;
3788
0
    goto err;
3789
0
  }
3790
3791
0
  if (fsize == expected_keylen) { /* it must be binary */
3792
0
    memcpy(tkey, keybuf, expected_keylen);
3793
0
  } else {
3794
    /* if the key-length is larger then binary length, we assume hex encoded */
3795
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Treating key as hex-encoded!\n");
3796
0
    sc_right_trim(keybuf, fsize);
3797
0
    keylen = expected_keylen;
3798
0
    r = sc_hex_to_bin((char *)keybuf, tkey, &keylen);
3799
0
    if (keylen != expected_keylen || r != 0) {
3800
0
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error formatting key\n");
3801
0
      if (r == 0)
3802
0
        r = SC_ERROR_INCOMPATIBLE_KEY;
3803
0
      goto err;
3804
0
    }
3805
0
  }
3806
0
  *key = tkey;
3807
0
  tkey = NULL;
3808
0
  *len = expected_keylen;
3809
0
  r = SC_SUCCESS;
3810
3811
0
err:
3812
0
  if (f)
3813
0
    fclose(f);
3814
0
  if (keybuf) {
3815
0
    free(keybuf);
3816
0
  }
3817
0
  if (tkey) {
3818
0
    free(tkey);
3819
0
  }
3820
3821
0
  LOG_FUNC_RETURN(card->ctx, r);
3822
0
  return r;
3823
0
}
3824
#endif
3825
3826
/*
3827
 * will only deal with 3des for now
3828
 * assumptions include:
3829
 *  size of encrypted data is same as unencrypted
3830
 *  challenges, nonces etc  from card are less then 114 (keeps tags simple)
3831
 */
3832
3833
static int
3834
piv_general_mutual_authenticate(sc_card_t *card,
3835
    unsigned int key_ref, unsigned int alg_id)
3836
0
{
3837
0
  int r;
3838
0
#ifdef ENABLE_OPENSSL
3839
0
  int N;
3840
0
  int locked = 0;
3841
0
  u8 rbuf[4096];
3842
0
  u8 *nonce = NULL;
3843
0
  size_t nonce_len;
3844
0
  u8 *p;
3845
0
  u8 *key = NULL;
3846
0
  size_t keylen;
3847
0
  u8 *plain_text = NULL;
3848
0
  size_t plain_text_len = 0;
3849
0
  u8 *tmp;
3850
0
  size_t tmplen, tmplen2;
3851
0
  u8 *built = NULL;
3852
0
  size_t built_len;
3853
0
  const u8 *body = NULL;
3854
0
  size_t body_len;
3855
0
  const u8 *witness_data = NULL;
3856
0
  size_t witness_len;
3857
0
  const u8 *challenge_response = NULL;
3858
0
  size_t challenge_response_len;
3859
0
  u8 *decrypted_reponse = NULL;
3860
0
  size_t decrypted_reponse_len;
3861
0
  EVP_CIPHER_CTX *ctx = NULL;
3862
3863
0
  u8 sbuf[255];
3864
0
  EVP_CIPHER *cipher = NULL;
3865
3866
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
3867
3868
0
  ctx = EVP_CIPHER_CTX_new();
3869
0
  if (ctx == NULL) {
3870
0
    sc_log_openssl(card->ctx);
3871
0
    r = SC_ERROR_OUT_OF_MEMORY;
3872
0
    goto err;
3873
0
  }
3874
3875
0
  cipher = get_cipher_for_algo(card, alg_id);
3876
0
  if (!cipher) {
3877
0
    sc_log_openssl(card->ctx);
3878
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for:  %02x\n", alg_id);
3879
0
    r = SC_ERROR_INVALID_ARGUMENTS;
3880
0
    goto err;
3881
0
  }
3882
3883
0
  r = piv_get_key(card, alg_id, &key, &keylen);
3884
0
  if (r) {
3885
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error getting General Auth key\n");
3886
0
    goto err;
3887
0
  }
3888
3889
0
  r = sc_lock(card);
3890
0
  if (r != SC_SUCCESS) {
3891
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "sc_lock failed\n");
3892
0
    goto err; /* cleanup */
3893
0
  }
3894
0
  locked = 1;
3895
3896
0
  p = sbuf;
3897
0
  *p++ = 0x7C;
3898
0
  *p++ = 0x02;
3899
0
  *p++ = 0x80;
3900
0
  *p++ = 0x00;
3901
3902
  /* get the encrypted nonce */
3903
0
  r = piv_general_io(card, 0x87, alg_id, key_ref, sbuf, p - sbuf, rbuf, sizeof rbuf);
3904
3905
0
  if (r < 0)
3906
0
    goto err;
3907
3908
  /* Remove the encompassing outer TLV of 0x7C and get the data */
3909
0
  body = sc_asn1_find_tag(card->ctx, rbuf,
3910
0
      r, 0x7C, &body_len);
3911
0
  if (!body || rbuf[0] != 0x7C) {
3912
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Witness Data response of NULL\n");
3913
0
    r = SC_ERROR_INVALID_DATA;
3914
0
    goto err;
3915
0
  }
3916
3917
  /* Get the witness data indicated by the TAG 0x80 */
3918
0
  witness_data = sc_asn1_find_tag(card->ctx, body,
3919
0
      body_len, 0x80, &witness_len);
3920
0
  if (!witness_len || body_len == 0 || body[0] != 0x80) {
3921
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data none found in TLV\n");
3922
0
    r = SC_ERROR_INVALID_DATA;
3923
0
    goto err;
3924
0
  }
3925
3926
  /* Allocate an output buffer for openssl */
3927
0
  plain_text = malloc(witness_len);
3928
0
  if (!plain_text) {
3929
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not allocate buffer for plain text\n");
3930
0
    r = SC_ERROR_INTERNAL;
3931
0
    goto err;
3932
0
  }
3933
3934
  /* decrypt the data from the card */
3935
0
  if (!EVP_DecryptInit(ctx, cipher, key, NULL)) {
3936
    /* may fail if des parity of key is wrong. depends on OpenSSL options */
3937
0
    sc_log_openssl(card->ctx);
3938
0
    r = SC_ERROR_INTERNAL;
3939
0
    goto err;
3940
0
  }
3941
0
  EVP_CIPHER_CTX_set_padding(ctx, 0);
3942
3943
0
  p = plain_text;
3944
0
  if (!EVP_DecryptUpdate(ctx, p, &N, witness_data, (int)witness_len)) {
3945
0
    sc_log_openssl(card->ctx);
3946
0
    r = SC_ERROR_INTERNAL;
3947
0
    goto err;
3948
0
  }
3949
0
  plain_text_len = tmplen = N;
3950
0
  p += tmplen;
3951
3952
0
  if (!EVP_DecryptFinal(ctx, p, &N)) {
3953
0
    sc_log_openssl(card->ctx);
3954
0
    r = SC_ERROR_INTERNAL;
3955
0
    goto err;
3956
0
  }
3957
0
  tmplen = N;
3958
0
  plain_text_len += tmplen;
3959
3960
0
  if (plain_text_len != witness_len) {
3961
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
3962
0
        "Encrypted and decrypted lengths do not match: %" SC_FORMAT_LEN_SIZE_T "u:%" SC_FORMAT_LEN_SIZE_T "u\n",
3963
0
        witness_len, plain_text_len);
3964
0
    r = SC_ERROR_INTERNAL;
3965
0
    goto err;
3966
0
  }
3967
3968
  /* Build a response to the card of:
3969
   * [GEN AUTH][ 80<decrypted witness>81 <challenge> ]
3970
   * Start by computing the nonce for <challenge> the
3971
   * nonce length should match the witness length of
3972
   * the card.
3973
   */
3974
0
  nonce = malloc(witness_len);
3975
0
  if (!nonce) {
3976
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
3977
0
        "OOM allocating nonce (%" SC_FORMAT_LEN_SIZE_T "u : %" SC_FORMAT_LEN_SIZE_T "u)\n",
3978
0
        witness_len, plain_text_len);
3979
0
    r = SC_ERROR_INTERNAL;
3980
0
    goto err;
3981
0
  }
3982
0
  nonce_len = witness_len;
3983
3984
0
  r = RAND_bytes(nonce, (int)witness_len);
3985
0
  if (!r) {
3986
0
    sc_log_openssl(card->ctx);
3987
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
3988
0
        "Generating random for nonce (%" SC_FORMAT_LEN_SIZE_T "u : %" SC_FORMAT_LEN_SIZE_T "u)\n",
3989
0
        witness_len, plain_text_len);
3990
0
    r = SC_ERROR_INTERNAL;
3991
0
    goto err;
3992
0
  }
3993
3994
  /* nonce for challenge */
3995
0
  r = sc_asn1_put_tag(0x81, NULL, witness_len, NULL, 0, NULL);
3996
0
  if (r <= 0) {
3997
0
    r = SC_ERROR_INTERNAL;
3998
0
    goto err;
3999
0
  }
4000
0
  tmplen = r;
4001
4002
  /* plain text witness keep a length separate for the 0x7C tag */
4003
0
  r = sc_asn1_put_tag(0x80, NULL, witness_len, NULL, 0, NULL);
4004
0
  if (r <= 0) {
4005
0
    r = SC_ERROR_INTERNAL;
4006
0
    goto err;
4007
0
  }
4008
0
  tmplen += r;
4009
0
  tmplen2 = tmplen;
4010
4011
  /* outside 7C tag with 81:80 as innards */
4012
0
  r = sc_asn1_put_tag(0x7C, NULL, tmplen, NULL, 0, NULL);
4013
0
  if (r <= 0) {
4014
0
    r = SC_ERROR_INTERNAL;
4015
0
    goto err;
4016
0
  }
4017
4018
0
  built_len = r;
4019
4020
  /* Build the response buffer */
4021
0
  p = built = malloc(built_len);
4022
0
  if (!built) {
4023
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "OOM Building witness response and challenge\n");
4024
0
    r = SC_ERROR_INTERNAL;
4025
0
    goto err;
4026
0
  }
4027
4028
0
  p = built;
4029
4030
  /* Start with the 7C Tag */
4031
0
  r = sc_asn1_put_tag(0x7C, NULL, tmplen2, p, built_len, &p);
4032
0
  if (r != SC_SUCCESS) {
4033
0
    goto err;
4034
0
  }
4035
4036
  /* Add the DECRYPTED witness, tag 0x80 */
4037
0
  r = sc_asn1_put_tag(0x80, plain_text, witness_len, p, built_len - (p - built), &p);
4038
0
  if (r != SC_SUCCESS) {
4039
0
    goto err;
4040
0
  }
4041
4042
  /* Add the challenge, tag 0x81 */
4043
0
  r = sc_asn1_put_tag(0x81, nonce, witness_len, p, built_len - (p - built), &p);
4044
0
  if (r != SC_SUCCESS) {
4045
0
    goto err;
4046
0
  }
4047
4048
  /* Send constructed data */
4049
0
  r = piv_general_io(card, 0x87, alg_id, key_ref, built, built_len, rbuf, sizeof rbuf);
4050
0
  if (r < 0) {
4051
0
    goto err;
4052
0
  }
4053
4054
  /* Remove the encompassing outer TLV of 0x7C and get the data */
4055
0
  body = sc_asn1_find_tag(card->ctx, rbuf,
4056
0
      r, 0x7C, &body_len);
4057
0
  if (!body || rbuf[0] != 0x7C) {
4058
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not find outer tag 0x7C in response");
4059
0
    r = SC_ERROR_INVALID_DATA;
4060
0
    goto err;
4061
0
  }
4062
4063
  /* SP800-73 not clear if  80 or 82 */
4064
0
  challenge_response = sc_asn1_find_tag(card->ctx, body,
4065
0
      body_len, 0x82, &challenge_response_len);
4066
0
  if (!challenge_response) {
4067
0
    challenge_response = sc_asn1_find_tag(card->ctx, body,
4068
0
        body_len, 0x80, &challenge_response_len);
4069
0
    if (!challenge_response) {
4070
0
      sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not find tag 0x82 or 0x80 in response");
4071
0
      r = SC_ERROR_INVALID_DATA;
4072
0
      goto err;
4073
0
    }
4074
0
  }
4075
4076
  /* Decrypt challenge and check against nonce */
4077
0
  decrypted_reponse = malloc(challenge_response_len);
4078
0
  if (!decrypted_reponse) {
4079
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "OOM Allocating decryption buffer");
4080
0
    r = SC_ERROR_INVALID_DATA;
4081
0
    goto err;
4082
0
  }
4083
4084
0
  EVP_CIPHER_CTX_reset(ctx);
4085
4086
0
  if (!EVP_DecryptInit(ctx, cipher, key, NULL)) {
4087
0
    sc_log_openssl(card->ctx);
4088
0
    r = SC_ERROR_INTERNAL;
4089
0
    goto err;
4090
0
  }
4091
0
  EVP_CIPHER_CTX_set_padding(ctx, 0);
4092
4093
0
  tmp = decrypted_reponse;
4094
0
  if (!EVP_DecryptUpdate(ctx, tmp, &N, challenge_response, (int)challenge_response_len)) {
4095
0
    sc_log_openssl(card->ctx);
4096
0
    r = SC_ERROR_INTERNAL;
4097
0
    goto err;
4098
0
  }
4099
0
  decrypted_reponse_len = tmplen = N;
4100
0
  tmp += tmplen;
4101
4102
0
  if (!EVP_DecryptFinal(ctx, tmp, &N)) {
4103
0
    sc_log_openssl(card->ctx);
4104
0
    r = SC_ERROR_INTERNAL;
4105
0
    goto err;
4106
0
  }
4107
0
  tmplen = N;
4108
0
  decrypted_reponse_len += tmplen;
4109
4110
0
  if (decrypted_reponse_len != nonce_len || memcmp(nonce, decrypted_reponse, nonce_len) != 0) {
4111
0
    sc_log(card->ctx,
4112
0
        "mutual authentication failed, card returned wrong value %" SC_FORMAT_LEN_SIZE_T "u:%" SC_FORMAT_LEN_SIZE_T "u",
4113
0
        decrypted_reponse_len, nonce_len);
4114
0
    r = SC_ERROR_DECRYPT_FAILED;
4115
0
    goto err;
4116
0
  }
4117
0
  r = SC_SUCCESS;
4118
4119
0
err:
4120
0
  sc_evp_cipher_free(cipher);
4121
0
  if (ctx)
4122
0
    EVP_CIPHER_CTX_free(ctx);
4123
0
  if (locked)
4124
0
    sc_unlock(card);
4125
0
  if (decrypted_reponse)
4126
0
    free(decrypted_reponse);
4127
0
  if (built)
4128
0
    free(built);
4129
0
  if (plain_text)
4130
0
    free(plain_text);
4131
0
  if (nonce)
4132
0
    free(nonce);
4133
0
  if (key)
4134
0
    free(key);
4135
4136
#else
4137
  sc_log(card->ctx, "OpenSSL Required");
4138
  r = SC_ERROR_NOT_SUPPORTED;
4139
#endif /* ENABLE_OPENSSL */
4140
4141
0
  LOG_FUNC_RETURN(card->ctx, r);
4142
0
}
4143
4144
/* Currently only used for card administration */
4145
static int
4146
piv_general_external_authenticate(sc_card_t *card,
4147
    unsigned int key_ref, unsigned int alg_id)
4148
0
{
4149
0
  int r;
4150
0
#ifdef ENABLE_OPENSSL
4151
0
  size_t tmplen;
4152
0
  int outlen;
4153
0
  int locked = 0;
4154
0
  u8 *p;
4155
0
  u8 rbuf[4096];
4156
0
  u8 *key = NULL;
4157
0
  u8 *cipher_text = NULL;
4158
0
  u8 *output_buf = NULL;
4159
0
  const u8 *body = NULL;
4160
0
  const u8 *challenge_data = NULL;
4161
0
  size_t body_len;
4162
0
  size_t output_len;
4163
0
  size_t challenge_len;
4164
0
  size_t keylen = 0;
4165
0
  size_t cipher_text_len = 0;
4166
0
  u8 sbuf[255];
4167
0
  EVP_CIPHER_CTX *ctx = NULL;
4168
0
  EVP_CIPHER *cipher = NULL;
4169
4170
0
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
4171
4172
0
  ctx = EVP_CIPHER_CTX_new();
4173
0
  if (ctx == NULL) {
4174
0
    sc_log_openssl(card->ctx);
4175
0
    r = SC_ERROR_OUT_OF_MEMORY;
4176
0
    goto err;
4177
0
  }
4178
4179
0
  sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Selected cipher for algorithm id: %02x\n", alg_id);
4180
4181
0
  cipher = get_cipher_for_algo(card, alg_id);
4182
0
  if (!cipher) {
4183
0
    sc_log_openssl(card->ctx);
4184
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid cipher selector, none found for:  %02x\n", alg_id);
4185
0
    r = SC_ERROR_INVALID_ARGUMENTS;
4186
0
    goto err;
4187
0
  }
4188
4189
0
  r = piv_get_key(card, alg_id, &key, &keylen);
4190
0
  if (r) {
4191
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error getting General Auth key\n");
4192
0
    goto err;
4193
0
  }
4194
4195
0
  r = sc_lock(card);
4196
0
  if (r != SC_SUCCESS) {
4197
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "sc_lock failed\n");
4198
0
    goto err; /* cleanup */
4199
0
  }
4200
0
  locked = 1;
4201
4202
0
  p = sbuf;
4203
0
  *p++ = 0x7C;
4204
0
  *p++ = 0x02;
4205
0
  *p++ = 0x81;
4206
0
  *p++ = 0x00;
4207
4208
  /* get a challenge */
4209
0
  r = piv_general_io(card, 0x87, alg_id, key_ref, sbuf, p - sbuf, rbuf, sizeof rbuf);
4210
0
  if (r < 0) {
4211
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Error getting Challenge\n");
4212
0
    goto err;
4213
0
  }
4214
4215
  /*
4216
   * the value here corresponds with the response size, so we use this
4217
   * to alloc the response buffer, rather than re-computing it.
4218
   */
4219
0
  output_len = r;
4220
4221
  /* Remove the encompassing outer TLV of 0x7C and get the data */
4222
0
  body = sc_asn1_find_tag(card->ctx, rbuf,
4223
0
      r, 0x7C, &body_len);
4224
0
  if (!body || rbuf[0] != 0x7C) {
4225
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data response of NULL\n");
4226
0
    r = SC_ERROR_INVALID_DATA;
4227
0
    goto err;
4228
0
  }
4229
4230
  /* Get the challenge data indicated by the TAG 0x81 */
4231
0
  challenge_data = sc_asn1_find_tag(card->ctx, body,
4232
0
      body_len, 0x81, &challenge_len);
4233
0
  if (!challenge_data) {
4234
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Invalid Challenge Data none found in TLV\n");
4235
0
    r = SC_ERROR_INVALID_DATA;
4236
0
    goto err;
4237
0
  }
4238
4239
  /* Store this to sanity check that plaintext length and ciphertext lengths match */
4240
0
  tmplen = challenge_len;
4241
4242
  /* Encrypt the challenge with the secret */
4243
0
  if (!EVP_EncryptInit(ctx, cipher, key, NULL)) {
4244
0
    sc_log_openssl(card->ctx);
4245
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt fail\n");
4246
0
    r = SC_ERROR_INTERNAL;
4247
0
    goto err;
4248
0
  }
4249
4250
0
  cipher_text = malloc(challenge_len);
4251
0
  if (!cipher_text) {
4252
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not allocate buffer for cipher text\n");
4253
0
    r = SC_ERROR_INTERNAL;
4254
0
    goto err;
4255
0
  }
4256
4257
0
  EVP_CIPHER_CTX_set_padding(ctx, 0);
4258
0
  if (!EVP_EncryptUpdate(ctx, cipher_text, &outlen, challenge_data, (int)challenge_len)) {
4259
0
    sc_log_openssl(card->ctx);
4260
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Encrypt update fail\n");
4261
0
    r = SC_ERROR_INTERNAL;
4262
0
    goto err;
4263
0
  }
4264
0
  cipher_text_len += outlen;
4265
4266
0
  if (!EVP_EncryptFinal(ctx, cipher_text + cipher_text_len, &outlen)) {
4267
0
    sc_log_openssl(card->ctx);
4268
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Final fail\n");
4269
0
    r = SC_ERROR_INTERNAL;
4270
0
    goto err;
4271
0
  }
4272
0
  cipher_text_len += outlen;
4273
4274
  /*
4275
   * Actually perform the sanity check on lengths plaintext length vs
4276
   * encrypted length
4277
   */
4278
0
  if (cipher_text_len != tmplen) {
4279
0
    sc_log_openssl(card->ctx);
4280
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Length test fail\n");
4281
0
    r = SC_ERROR_INTERNAL;
4282
0
    goto err;
4283
0
  }
4284
4285
0
  output_buf = malloc(output_len);
4286
0
  if (!output_buf) {
4287
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not allocate output buffer: %s\n",
4288
0
        strerror(errno));
4289
0
    r = SC_ERROR_INTERNAL;
4290
0
    goto err;
4291
0
  }
4292
4293
0
  p = output_buf;
4294
4295
  /*
4296
   * Build: 7C<len>[82<len><challenge>]
4297
   * Start off by capturing the data of the response:
4298
   *     - 82<len><encrypted challenege response>
4299
   * Build the outside TLV (7C)
4300
   * Advance past that tag + len
4301
   * Build the body (82)
4302
   * memcopy the body past the 7C<len> portion
4303
   * Transmit
4304
   */
4305
0
  tmplen = sc_asn1_put_tag(0x82, NULL, cipher_text_len, NULL, 0, NULL);
4306
0
  if (tmplen <= 0) {
4307
0
    r = SC_ERROR_INTERNAL;
4308
0
    goto err;
4309
0
  }
4310
4311
0
  r = sc_asn1_put_tag(0x7C, NULL, tmplen, p, output_len, &p);
4312
0
  if (r != SC_SUCCESS) {
4313
0
    goto err;
4314
0
  }
4315
4316
  /* Build the 0x82 TLV and append to the 7C<len> tag */
4317
0
  r = sc_asn1_put_tag(0x82, cipher_text, cipher_text_len, p, output_len - (p - output_buf), &p);
4318
0
  if (r != SC_SUCCESS) {
4319
0
    goto err;
4320
0
  }
4321
4322
  /* Sanity check the lengths again */
4323
0
  tmplen = sc_asn1_put_tag(0x7C, NULL, tmplen, NULL, 0, NULL);
4324
0
  if (output_len != (size_t)tmplen) {
4325
0
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Allocated and computed lengths do not match! "
4326
0
                "Expected %" SC_FORMAT_LEN_SIZE_T "d, found: %zu\n",
4327
0
        output_len, tmplen);
4328
0
    r = SC_ERROR_INTERNAL;
4329
0
    goto err;
4330
0
  }
4331
4332
0
  r = piv_general_io(card, 0x87, alg_id, key_ref, output_buf, output_len, NULL, 0);
4333
0
  sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Got response  challenge\n");
4334
4335
0
err:
4336
0
  sc_evp_cipher_free(cipher);
4337
0
  if (ctx)
4338
0
    EVP_CIPHER_CTX_free(ctx);
4339
4340
0
  if (locked)
4341
0
    sc_unlock(card);
4342
4343
0
  if (key) {
4344
0
    sc_mem_clear(key, keylen);
4345
0
    free(key);
4346
0
  }
4347
4348
0
  if (cipher_text)
4349
0
    free(cipher_text);
4350
4351
0
  if (output_buf)
4352
0
    free(output_buf);
4353
#else
4354
  sc_log(card->ctx, "OpenSSL Required");
4355
  r = SC_ERROR_NOT_SUPPORTED;
4356
#endif /* ENABLE_OPENSSL */
4357
4358
0
  LOG_FUNC_RETURN(card->ctx, r);
4359
0
}
4360
4361
/*
4362
 * with sp800-73-4 and SM GUID is also in sm_cvc.subjectID
4363
 */
4364
static int
4365
piv_get_serial_nr_from_CHUI(sc_card_t *card, sc_serial_number_t *serial)
4366
667
{
4367
667
  int r;
4368
667
  int i;
4369
667
  u8 gbits = 0; /* 0 not present or wrong length or all zeros */
4370
667
  u8 fbits = 0; /* 0 not present or wrong length or all zeros */
4371
667
  u8 *rbuf = NULL;
4372
667
  const u8 *body;
4373
667
  const u8 *fascn;
4374
667
  const u8 *guid;
4375
667
  size_t rbuflen = 0, bodylen, fascnlen, guidlen;
4376
4377
667
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
4378
667
  if (card->serialnr.len) {
4379
0
    *serial = card->serialnr;
4380
0
    LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
4381
0
  }
4382
4383
  /*
4384
   * 800-73-3 Part 1 and CIO Council docs say for PIV Compatible cards
4385
   * the FASC-N Agency code should be 9999 and there should be a GUID
4386
   * based on RFC 4122. If GUID present and not zero
4387
   * we will use the GUID as the serial number.
4388
   */
4389
4390
667
  r = piv_get_cached_data(card, PIV_OBJ_CHUI, &rbuf, &rbuflen);
4391
667
  LOG_TEST_RET(card->ctx, r, "Failure retrieving CHUI");
4392
4393
72
  r = SC_ERROR_INTERNAL;
4394
72
  if (rbuflen != 0) {
4395
72
    body = sc_asn1_find_tag(card->ctx, rbuf, rbuflen, 0x53, &bodylen); /* Pass the outer wrapper asn1 */
4396
72
    if (body != NULL && bodylen != 0 && rbuf[0] == 0x53) {
4397
70
      fascn = sc_asn1_find_tag(card->ctx, body, bodylen, 0x30, &fascnlen); /* Find the FASC-N data */
4398
4399
70
      if (fascn && fascnlen == 25) {
4400
572
        for (i = 0; i < 25; i++) {
4401
550
          fbits = fbits || fascn[i]; /* if all are zero, gbits will be zero */
4402
550
        }
4403
22
      }
4404
4405
70
      guid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x34, &guidlen);
4406
4407
70
      if (guid && guidlen == 16) {
4408
170
        for (i = 0; i < 16; i++) {
4409
160
          gbits = gbits | guid[i]; /* if all are zero, gbits will be zero */
4410
160
        }
4411
10
      }
4412
70
      sc_log(card->ctx,
4413
70
          "fascn=%p,fascnlen=%" SC_FORMAT_LEN_SIZE_T "u,guid=%p,guidlen=%" SC_FORMAT_LEN_SIZE_T "u,gbits=%2.2x",
4414
70
          fascn, fascnlen, guid, guidlen, gbits);
4415
4416
70
      if (fascn && fascnlen == 25 && fbits) {
4417
        /* test if guid and the fascn starts with ;9999 (in ISO 4bit + parity code) */
4418
        /* ;9999 is non-gov issued FASC-N, will use FASC-N for gov issued if no guid */
4419
21
        if (!(gbits && fascn[0] == 0xD4 && fascn[1] == 0xE7 &&
4420
20
                fascn[2] == 0x39 && (fascn[3] | 0x7F) == 0xFF)) {
4421
          /* fascnlen is 25 */
4422
20
          serial->len = fascnlen;
4423
20
          memcpy(serial->value, fascn, serial->len);
4424
20
          r = SC_SUCCESS;
4425
20
          gbits = 0; /* set to skip using guid below */
4426
20
        }
4427
21
      }
4428
70
      if (guid && guidlen == 16 && gbits) {
4429
4
        serial->len = guidlen;
4430
4
        memcpy(serial->value, guid, serial->len);
4431
4
        r = SC_SUCCESS;
4432
4
      }
4433
70
    }
4434
72
  }
4435
4436
72
  if (fbits == 0 && gbits == 0) { /* were not able to set the serial number */
4437
48
    serial->len = 16;
4438
48
    memset(serial->value, 0x00, serial->len);
4439
48
    r = SC_ERROR_INTERNAL;
4440
48
  }
4441
4442
72
  card->serialnr = *serial;
4443
72
  LOG_FUNC_RETURN(card->ctx, r);
4444
72
}
4445
4446
/*
4447
 * If the object can not be present on the card, because the History
4448
 * object is not present or the History object says its not present,
4449
 * return 1. If object may be present return 0.
4450
 * Cuts down on overhead, by not showing non existent objects to pkcs11
4451
 * The path for the object is passed in and the first 2 bytes are used.
4452
 * Note: If the History or Discovery object is not found the
4453
 * PIV_OBJ_CACHE_NOT_PRESENT is set, as older cards do not have these.
4454
 * pkcs15-piv.c calls this via cardctl.
4455
 */
4456
4457
static int
4458
piv_is_object_present(sc_card_t *card, u8 *ptr)
4459
41.3k
{
4460
41.3k
  piv_private_data_t *priv = PIV_DATA(card);
4461
41.3k
  int r = 0;
4462
41.3k
  int enumtag;
4463
4464
41.3k
  enumtag = piv_find_obj_by_containerid(card, ptr);
4465
41.3k
  if (enumtag >= 0 && priv->obj_cache[enumtag].flags & PIV_OBJ_CACHE_NOT_PRESENT)
4466
26.7k
    r = 1;
4467
4468
41.3k
  LOG_FUNC_RETURN(card->ctx, r);
4469
41.3k
}
4470
4471
/*
4472
 * NIST 800-73-3 allows the default pin to be the PIV application 0x80
4473
 * or the global pin for the card 0x00. Look at Discovery object to get this.
4474
 * called by pkcs15-piv.c  via cardctl when setting up the pins.
4475
 */
4476
static int
4477
piv_get_pin_preference(sc_card_t *card, int *pin_ref)
4478
667
{
4479
667
  piv_private_data_t *priv = PIV_DATA(card);
4480
4481
667
  *pin_ref = priv->pin_preference;
4482
667
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
4483
667
}
4484
4485
static int
4486
piv_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
4487
42.6k
{
4488
42.6k
  piv_private_data_t *priv = PIV_DATA(card);
4489
42.6k
  u8 *opts; /*  A or M, key_ref, alg_id */
4490
4491
42.6k
  LOG_FUNC_CALLED(card->ctx);
4492
4493
42.6k
  if (priv == NULL) {
4494
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
4495
0
  }
4496
42.6k
  switch (cmd) {
4497
0
  case SC_CARDCTL_PIV_AUTHENTICATE:
4498
0
    opts = (u8 *)ptr;
4499
0
    switch (*opts) {
4500
0
    case 'A':
4501
0
      return piv_general_external_authenticate(card,
4502
0
          *(opts + 1), *(opts + 2));
4503
0
      break;
4504
0
    case 'M':
4505
0
      return piv_general_mutual_authenticate(card,
4506
0
          *(opts + 1), *(opts + 2));
4507
0
      break;
4508
0
    }
4509
0
    break;
4510
0
  case SC_CARDCTL_PIV_GENERATE_KEY:
4511
0
    return piv_generate_key(card,
4512
0
        (sc_cardctl_piv_genkey_info_t *)ptr);
4513
0
    break;
4514
667
  case SC_CARDCTL_GET_SERIALNR:
4515
667
    return piv_get_serial_nr_from_CHUI(card, (sc_serial_number_t *)ptr);
4516
0
    break;
4517
667
  case SC_CARDCTL_PIV_PIN_PREFERENCE:
4518
667
    return piv_get_pin_preference(card, ptr);
4519
0
    break;
4520
41.3k
  case SC_CARDCTL_PIV_OBJECT_PRESENT:
4521
41.3k
    return piv_is_object_present(card, ptr);
4522
0
    break;
4523
42.6k
  }
4524
4525
0
  LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
4526
0
}
4527
4528
static int
4529
piv_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
4530
0
{
4531
  /* Dynamic Authentication Template (Challenge) */
4532
0
  u8 sbuf[] = {0x7c, 0x02, 0x81, 0x00};
4533
0
  u8 rbuf[4096];
4534
0
  const u8 *p;
4535
0
  size_t out_len = 0;
4536
0
  int r;
4537
0
  unsigned int tag_out = 0, cla_out = 0;
4538
0
  piv_private_data_t *priv = PIV_DATA(card);
4539
4540
0
  LOG_FUNC_CALLED(card->ctx);
4541
4542
0
  if (priv->card_issues & CI_NO_RANDOM) {
4543
0
    r = SC_ERROR_NOT_SUPPORTED;
4544
0
    LOG_TEST_GOTO_ERR(card->ctx, r, "No support for random data");
4545
0
  }
4546
4547
  /* NIST 800-73-3 says use 9B, previous versions used 00 */
4548
0
  r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, rbuf, sizeof rbuf);
4549
  /*
4550
   * piv_get_challenge is called in a loop.
4551
   * some cards may allow 1 challenge expecting it to be part of
4552
   * NIST 800-73-3 part 2 "Authentication of PIV Card Application Administrator"
4553
   * and return "6A 80" if last command was a get_challenge.
4554
   * Now that the card returned error, we can try one more time.
4555
   */
4556
0
  if (r == SC_ERROR_INCORRECT_PARAMETERS) {
4557
0
    r = piv_general_io(card, 0x87, 0x00, 0x9B, sbuf, sizeof sbuf, rbuf, sizeof rbuf);
4558
0
    if (r == SC_ERROR_INCORRECT_PARAMETERS) {
4559
0
      r = SC_ERROR_NOT_SUPPORTED;
4560
0
    }
4561
0
  }
4562
0
  LOG_TEST_GOTO_ERR(card->ctx, r, "GENERAL AUTHENTICATE failed");
4563
4564
0
  p = rbuf;
4565
0
  r = sc_asn1_read_tag(&p, r, &cla_out, &tag_out, &out_len);
4566
0
  if (r < 0 || (cla_out | tag_out) != 0x7C) {
4567
0
    LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Dynamic Authentication Template");
4568
0
  }
4569
4570
0
  r = sc_asn1_read_tag(&p, out_len, &cla_out, &tag_out, &out_len);
4571
0
  if (r < 0 || (cla_out | tag_out) != 0x81) {
4572
0
    LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find Challenge");
4573
0
  }
4574
4575
0
  if (len < out_len) {
4576
0
    out_len = len;
4577
0
  }
4578
0
  memcpy(rnd, p, out_len);
4579
4580
0
  r = (int)out_len;
4581
4582
0
err:
4583
0
  LOG_FUNC_RETURN(card->ctx, r);
4584
0
}
4585
4586
static int
4587
piv_set_security_env(sc_card_t *card, const sc_security_env_t *env, int se_num)
4588
30
{
4589
30
  piv_private_data_t *priv = PIV_DATA(card);
4590
30
  int r = 0;
4591
4592
30
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
4593
4594
30
  sc_log(card->ctx,
4595
30
      "flags=%08lx op=%d alg=%lu algf=%08lx algr=%08lx kr0=%02x, krfl=%" SC_FORMAT_LEN_SIZE_T "u",
4596
30
      env->flags, env->operation, env->algorithm, env->algorithm_flags,
4597
30
      env->algorithm_ref, env->key_ref[0], env->key_ref_len);
4598
4599
30
  priv->operation = env->operation;
4600
30
  priv->algorithm = env->algorithm;
4601
4602
30
  if (env->algorithm == SC_ALGORITHM_RSA) {
4603
14
    priv->alg_id = 0x06; /* Say it is RSA, set 5, 6, 7 later */
4604
16
  } else if (env->algorithm == SC_ALGORITHM_EC) {
4605
16
    if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
4606
16
      switch (env->algorithm_ref) {
4607
16
      case 256:
4608
16
        priv->alg_id = 0x11; /* Say it is EC 256 */
4609
16
        priv->key_size = 256;
4610
16
        break;
4611
0
      case 384:
4612
0
        priv->alg_id = 0x14;
4613
0
        priv->key_size = 384;
4614
0
        break;
4615
0
      default:
4616
0
        r = SC_ERROR_NO_CARD_SUPPORT;
4617
16
      }
4618
16
    } else
4619
0
      r = SC_ERROR_NO_CARD_SUPPORT;
4620
16
  } else if (env->algorithm == SC_ALGORITHM_EDDSA) {
4621
0
    priv->alg_id = 0xE0;
4622
0
    priv->key_size = 255;
4623
0
  } else if (env->algorithm == SC_ALGORITHM_XEDDSA) {
4624
0
    priv->alg_id = 0xE1;
4625
0
    priv->key_size = 255;
4626
0
  } else
4627
0
    r = SC_ERROR_NO_CARD_SUPPORT;
4628
30
  priv->key_ref = env->key_ref[0];
4629
4630
30
  LOG_FUNC_RETURN(card->ctx, r);
4631
30
}
4632
4633
static int
4634
piv_restore_security_env(sc_card_t *card, int se_num)
4635
0
{
4636
0
  LOG_FUNC_CALLED(card->ctx);
4637
4638
0
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
4639
0
}
4640
4641
static int
4642
piv_validate_general_authentication(sc_card_t *card,
4643
    const u8 *data, size_t datalen,
4644
    u8 *out, size_t outlen)
4645
30
{
4646
30
  piv_private_data_t *priv = PIV_DATA(card);
4647
30
  int r, tmplen, tmplen2;
4648
30
  u8 *p;
4649
30
  const unsigned char *p2;
4650
30
  size_t taglen;
4651
30
  size_t bodylen;
4652
30
  unsigned int cla, tag;
4653
30
  unsigned int real_alg_id, op_tag;
4654
4655
30
  u8 sbuf[4096]; /* needs work. for 4096 needs 512+10 or so */
4656
30
  size_t sbuflen = sizeof(sbuf);
4657
30
  u8 rbuf[4096];
4658
4659
30
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
4660
4661
  /* should assume large send data */
4662
30
  p = sbuf;
4663
30
  tmplen = sc_asn1_put_tag(0xff, NULL, datalen, NULL, 0, NULL);
4664
30
  tmplen2 = sc_asn1_put_tag(0x82, NULL, 0, NULL, 0, NULL);
4665
30
  if (tmplen <= 0 || tmplen2 <= 0) {
4666
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
4667
0
  }
4668
30
  tmplen += tmplen2;
4669
30
  if ((r = sc_asn1_put_tag(0x7c, NULL, tmplen, p, sbuflen, &p)) != SC_SUCCESS ||
4670
30
      (r = sc_asn1_put_tag(0x82, NULL, 0, p, sbuflen - (p - sbuf), &p)) != SC_SUCCESS) {
4671
0
    LOG_FUNC_RETURN(card->ctx, r);
4672
0
  }
4673
30
  if (priv->operation == SC_SEC_OPERATION_DERIVE && (priv->algorithm == SC_ALGORITHM_EC || priv->algorithm == SC_ALGORITHM_XEDDSA)) {
4674
0
    op_tag = 0x85;
4675
30
  } else {
4676
30
    op_tag = 0x81;
4677
30
  }
4678
30
  r = sc_asn1_put_tag(op_tag, data, datalen, p, sbuflen - (p - sbuf), &p);
4679
30
  if (r != SC_SUCCESS) {
4680
0
    LOG_FUNC_RETURN(card->ctx, r);
4681
0
  }
4682
4683
  /*
4684
   * alg_id=06 is a place holder for all RSA keys.
4685
   * Derive the real alg_id based on the size of the
4686
   * the data, as we are always using raw mode.
4687
   * Non RSA keys needs some work in this area.
4688
   */
4689
4690
30
  real_alg_id = priv->alg_id;
4691
30
  if (priv->alg_id == 0x06) {
4692
14
    switch (datalen) {
4693
0
    case 128:
4694
0
      real_alg_id = 0x06;
4695
0
      break;
4696
10
    case 256:
4697
10
      real_alg_id = 0x07;
4698
10
      break;
4699
0
    case 384:
4700
0
      real_alg_id = 0x05;
4701
0
      break;
4702
0
    case 512:
4703
0
      real_alg_id = 0x16;
4704
0
      break;
4705
4
    default:
4706
4
      SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_NO_CARD_SUPPORT);
4707
14
    }
4708
14
  }
4709
  /* EC and ED alg_id was already set */
4710
4711
26
  r = piv_general_io(card, 0x87, real_alg_id, priv->key_ref,
4712
26
      sbuf, p - sbuf, rbuf, sizeof rbuf);
4713
26
  if (r < 0)
4714
15
    goto err;
4715
4716
11
  p2 = rbuf;
4717
11
  r = sc_asn1_read_tag(&p2, r, &cla, &tag, &bodylen);
4718
11
  if (p2 == NULL || r < 0 || bodylen == 0 || (cla | tag) != 0x7C) {
4719
6
    LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x7C");
4720
6
  }
4721
4722
5
  r = sc_asn1_read_tag(&p2, bodylen, &cla, &tag, &taglen);
4723
5
  if (p2 == NULL || r < 0 || taglen == 0 || (cla | tag) != 0x82) {
4724
4
    LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "Can't find 0x82");
4725
4
  }
4726
4727
1
  if (taglen > outlen) {
4728
0
    LOG_TEST_GOTO_ERR(card->ctx, SC_ERROR_INVALID_DATA, "data read longer then buffer");
4729
0
  }
4730
4731
1
  memcpy(out, p2, taglen);
4732
1
  r = (int)taglen;
4733
4734
26
err:
4735
26
  LOG_FUNC_RETURN(card->ctx, r);
4736
26
}
4737
4738
static int
4739
piv_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
4740
    u8 *out, size_t outlen)
4741
17
{
4742
17
  piv_private_data_t *priv = PIV_DATA(card);
4743
17
  int r;
4744
17
  size_t nLen;
4745
17
  u8 rbuf[128]; /* For EC conversions  384 will fit */
4746
4747
17
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
4748
  /* The PIV returns a DER SEQUENCE{INTEGER, INTEGER}
4749
   * Which may have leading 00 to force a positive integer
4750
   * But PKCS11 just wants 2* field_length in bytes
4751
   * So we have to strip out the integers
4752
   * and pad on left if too short.
4753
   */
4754
4755
17
  if (priv->alg_id == 0x11 || priv->alg_id == 0x14) {
4756
16
    nLen = BYTES4BITS(priv->key_size);
4757
16
    if (outlen < 2 * nLen) {
4758
0
      sc_log(card->ctx,
4759
0
          " output too small for EC signature %" SC_FORMAT_LEN_SIZE_T "u < %" SC_FORMAT_LEN_SIZE_T "u",
4760
0
          outlen, 2 * nLen);
4761
0
      r = SC_ERROR_INVALID_DATA;
4762
0
      goto err;
4763
0
    }
4764
4765
16
    r = piv_validate_general_authentication(card, data, datalen, rbuf, sizeof rbuf);
4766
16
    if (r < 0)
4767
14
      goto err;
4768
4769
2
    r = sc_asn1_decode_ecdsa_signature(card->ctx, rbuf, r, nLen, &out, outlen);
4770
    /* Yubikey 5.7.x supports ED25519 */
4771
2
  } else if (priv->alg_id == 0xE0) {
4772
0
    nLen = BYTES4BITS(priv->key_size);
4773
0
    if (outlen < nLen) {
4774
0
      sc_log(card->ctx,
4775
0
          " output too small for ED signature %" SC_FORMAT_LEN_SIZE_T "u < %" SC_FORMAT_LEN_SIZE_T "u",
4776
0
          outlen, nLen);
4777
0
      r = SC_ERROR_INVALID_DATA;
4778
0
      goto err;
4779
0
    }
4780
0
    r = piv_validate_general_authentication(card, data, datalen, out, outlen);
4781
4782
1
  } else { /* RSA is all set */
4783
1
    r = piv_validate_general_authentication(card, data, datalen, out, outlen);
4784
1
  }
4785
4786
17
err:
4787
17
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
4788
17
}
4789
4790
static int
4791
piv_decipher(sc_card_t *card, const u8 *data, size_t datalen, u8 *out, size_t outlen)
4792
13
{
4793
13
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
4794
4795
13
  SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, piv_validate_general_authentication(card, data, datalen, out, outlen));
4796
13
}
4797
4798
/*
4799
 * the PIV-II does not always support files, but we will simulate
4800
 * files and reading/writing using get/put_data
4801
 * The path is the containerID number
4802
 * We can use this to determine the type of data requested, like a cert
4803
 * or pub key.
4804
 * We only support write from the piv_tool with file_out==NULL
4805
 * All other requests should be to read.
4806
 * Only if file_out != null, will we read to get length.
4807
 */
4808
static int
4809
piv_select_file(sc_card_t *card, const sc_path_t *in_path,
4810
    sc_file_t **file_out)
4811
5.39k
{
4812
5.39k
  piv_private_data_t *priv = PIV_DATA(card);
4813
5.39k
  int r;
4814
5.39k
  int i;
4815
5.39k
  const u8 *path;
4816
5.39k
  size_t pathlen;
4817
5.39k
  sc_file_t *file = NULL;
4818
5.39k
  u8 *rbuf = NULL;
4819
5.39k
  size_t rbuflen = 0;
4820
4821
5.39k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
4822
4823
5.39k
  path = in_path->value;
4824
5.39k
  pathlen = in_path->len;
4825
4826
  /* only support single EF in current application */
4827
  /*
4828
   * PIV emulates files, and only does so because sc_pkcs15_* uses
4829
   * select_file and read_binary. The emulation adds path emulated structures
4830
   * so piv_select_file will find it.
4831
   * there is no dir. Only direct access to emulated files
4832
   * thus opensc-tool and opensc-explorer can not read the emulated files
4833
   */
4834
4835
5.39k
  if (memcmp(path, "\x3F\x00", 2) == 0) {
4836
1.50k
    if (pathlen > 2) {
4837
1.50k
      path += 2;
4838
1.50k
      pathlen -= 2;
4839
1.50k
    }
4840
1.50k
  }
4841
4842
5.39k
  i = piv_find_obj_by_containerid(card, path);
4843
4844
5.39k
  if (i < 0)
4845
5.39k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND);
4846
4847
  /*
4848
   * pkcs15 will use a 2 byte path or a 4 byte path
4849
   * with cece added to path to request only the cert from the cert obj
4850
   * PIV "Container ID" is used as the path, and are two bytes long
4851
   */
4852
3.86k
  priv->return_only_cert = (pathlen == 4 && path[2] == 0xce && path[3] == 0xce);
4853
4854
3.86k
  priv->selected_obj = i;
4855
3.86k
  priv->rwb_state = -1;
4856
4857
  /* make it look like the file was found. */
4858
  /* We don't want to read it now  unless we need the length */
4859
4860
3.86k
  if (file_out) {
4861
    /* we need to read it now, to get length into cache */
4862
3.86k
    r = piv_get_cached_data(card, i, &rbuf, &rbuflen);
4863
4864
3.86k
    if (r < 0)
4865
3.86k
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_FILE_NOT_FOUND);
4866
4867
    /* get the cert or the pub key out and into the cache too */
4868
520
    if (priv->return_only_cert || piv_objects[i].flags & PIV_OBJECT_TYPE_PUBKEY) {
4869
520
      r = piv_cache_internal_data(card, i);
4870
520
      if (r < 0)
4871
520
        LOG_FUNC_RETURN(card->ctx, r);
4872
520
    }
4873
4874
408
    file = sc_file_new();
4875
408
    if (file == NULL)
4876
408
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
4877
4878
408
    file->path = *in_path;
4879
    /* this could be like the FCI */
4880
408
    file->type = SC_FILE_TYPE_DF;
4881
408
    file->shareable = 0;
4882
408
    file->ef_structure = 0;
4883
408
    if (priv->return_only_cert)
4884
408
      file->size = priv->obj_cache[i].internal_obj_len;
4885
0
    else
4886
0
      file->size = priv->obj_cache[i].obj_len;
4887
4888
408
    file->id = (piv_objects[i].containerid[0] << 8) + piv_objects[i].containerid[1];
4889
4890
408
    *file_out = file;
4891
408
  }
4892
4893
408
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
4894
408
}
4895
4896
static int
4897
piv_parse_discovery(sc_card_t *card, u8 *rbuf, size_t rbuflen, int aid_only)
4898
89
{
4899
89
  piv_private_data_t *priv = PIV_DATA(card);
4900
89
  int r = 0;
4901
89
  const u8 *body;
4902
89
  size_t bodylen;
4903
89
  const u8 *aid;
4904
89
  size_t aidlen;
4905
89
  const u8 *pinp;
4906
89
  size_t pinplen;
4907
89
  unsigned int cla_out, tag_out;
4908
4909
89
  if (rbuflen != 0) {
4910
89
    body = rbuf;
4911
89
    if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS ||
4912
89
        body == NULL ||
4913
89
        bodylen == 0 ||
4914
88
        ((cla_out | tag_out) != 0x7E)) {
4915
1
      sc_log(card->ctx, "DER problem %d", r);
4916
1
      r = SC_ERROR_INVALID_ASN1_OBJECT;
4917
1
      goto err;
4918
1
    }
4919
4920
88
    sc_log(card->ctx,
4921
88
        "Discovery 0x%2.2x 0x%2.2x %p:%" SC_FORMAT_LEN_SIZE_T "u",
4922
88
        cla_out, tag_out, body, bodylen);
4923
88
    aidlen = 0;
4924
88
    aid = sc_asn1_find_tag(card->ctx, body, bodylen, 0x4F, &aidlen);
4925
88
    if (aid == NULL || aidlen < piv_aids[0].len_short ||
4926
75
        memcmp(aid, piv_aids[0].value, piv_aids[0].len_short) != 0) {
4927
48
      sc_log(card->ctx, "Discovery object not PIV");
4928
48
      r = SC_ERROR_INVALID_CARD; /* This is an error */
4929
48
      goto err;
4930
48
    }
4931
40
    if (aid_only == 0) {
4932
40
      pinp = sc_asn1_find_tag(card->ctx, body, bodylen, 0x5F2F, &pinplen);
4933
40
      if (pinp && pinplen == 2) {
4934
8
        priv->init_flags |= PIV_INIT_DISCOVERY_PP;
4935
8
        priv->pin_policy = (*pinp << 8) + *(pinp + 1);
4936
8
        sc_log(card->ctx, "Discovery pinp flags=0x%2.2x 0x%2.2x", *pinp, *(pinp + 1));
4937
8
        if ((priv->pin_policy & (PIV_PP_PIN | PIV_PP_GLOBAL)) == (PIV_PP_PIN | PIV_PP_GLOBAL) &&
4938
3
            priv->pin_policy & PIV_PP_GLOBAL_PRIMARY) {
4939
1
          sc_log(card->ctx, "Pin Preference - Global");
4940
1
          priv->pin_preference = 0x00;
4941
1
        }
4942
8
      }
4943
40
    }
4944
40
    r = SC_SUCCESS;
4945
40
    priv->init_flags |= PIV_INIT_DISCOVERY_PARSED;
4946
40
  }
4947
4948
89
err:
4949
89
  LOG_FUNC_RETURN(card->ctx, r);
4950
89
}
4951
4952
/* normal way to get the discovery object via cache */
4953
static int
4954
piv_process_discovery(sc_card_t *card)
4955
904
{
4956
904
  int r;
4957
904
  u8 *rbuf = NULL;
4958
904
  size_t rbuflen = 0;
4959
4960
904
  r = piv_get_cached_data(card, PIV_OBJ_DISCOVERY, &rbuf, &rbuflen);
4961
  /* Note rbuf and rbuflen are now pointers into cache */
4962
904
  if (r < 0)
4963
815
    goto err;
4964
4965
  /* the object is now cached, see what we have */
4966
89
  r = piv_parse_discovery(card, rbuf, rbuflen, 0);
4967
4968
904
err:
4969
904
  LOG_FUNC_RETURN(card->ctx, r);
4970
904
}
4971
4972
/*
4973
 * parse a CCC to test  if this is a Dual CAC/PIV
4974
 * We read the CCC using the PIV API.
4975
 * Look for CAC RID=A0 00 00 00 79
4976
 */
4977
static int
4978
piv_parse_ccc(sc_card_t *card, u8 *rbuf, size_t rbuflen)
4979
64
{
4980
64
  int r = 0;
4981
64
  const u8 *body;
4982
64
  size_t bodylen;
4983
64
  unsigned int cla_out, tag_out;
4984
4985
64
  u8 tag;
4986
64
  const u8 *end;
4987
64
  size_t len;
4988
4989
64
  piv_private_data_t *priv = PIV_DATA(card);
4990
4991
64
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
4992
4993
64
  if (rbuf == NULL || rbuflen == 0) {
4994
0
    r = SC_ERROR_WRONG_LENGTH;
4995
0
    goto err;
4996
0
  }
4997
4998
  /* Outer layer is a DER tlv */
4999
64
  body = rbuf;
5000
64
  if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS ||
5001
64
      body == NULL ||
5002
64
      bodylen == 0 ||
5003
62
      ((cla_out << 24 | tag_out) != piv_objects[PIV_OBJ_CCC].resp_tag)) {
5004
2
    sc_log(card->ctx, "DER problem %d", r);
5005
2
    r = SC_ERROR_INVALID_ASN1_OBJECT;
5006
2
    goto err;
5007
2
  }
5008
5009
62
  priv->ccc_flags |= PIV_CCC_FOUND;
5010
5011
  /* CCC  entries are simple tlv */
5012
62
  end = body + bodylen;
5013
4.01k
  for (; (body < end); body += len) {
5014
4.00k
    r = sc_simpletlv_read_tag(&body, end - body, &tag, &len);
5015
4.00k
    if (r < 0)
5016
55
      goto err;
5017
3.95k
    switch (tag) {
5018
154
    case PIV_CCC_TAG_F0:
5019
154
      if (len == 0x15) {
5020
66
        if (memcmp(body, "\xA0\x00\x00\x03\08", 5) == 0)
5021
21
          priv->ccc_flags |= PIV_CCC_F0_PIV;
5022
45
        else if (memcmp(body, "\xA0\x00\x00\x00\x79", 5) == 0)
5023
11
          priv->ccc_flags |= PIV_CCC_F0_CAC;
5024
66
        if (*(body + 6) == 0x02)
5025
15
          priv->ccc_flags |= PIV_CCC_F0_JAVA;
5026
66
      }
5027
154
      break;
5028
156
    case PIV_CCC_TAG_F3:
5029
156
      if (len == 0x10) {
5030
49
        if (memcmp(body, "\xA0\x00\x00\x00\x79\x04", 6) == 0)
5031
22
          priv->ccc_flags |= PIV_CCC_F3_CAC_PKI;
5032
49
      }
5033
156
      break;
5034
3.95k
    }
5035
3.95k
  }
5036
5037
64
err:
5038
64
  LOG_FUNC_RETURN(card->ctx, r);
5039
64
}
5040
5041
static int
5042
piv_process_ccc(sc_card_t *card)
5043
487
{
5044
487
  int r = 0;
5045
487
  u8 *rbuf = NULL;
5046
487
  size_t rbuflen = 0;
5047
5048
487
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
5049
487
  r = piv_get_cached_data(card, PIV_OBJ_CCC, &rbuf, &rbuflen);
5050
5051
487
  if (r < 0)
5052
423
    goto err;
5053
5054
  /* the object is now cached, see what we have */
5055
64
  r = piv_parse_ccc(card, rbuf, rbuflen);
5056
487
err:
5057
487
  LOG_FUNC_RETURN(card->ctx, r);
5058
487
}
5059
5060
static int
5061
piv_find_discovery(sc_card_t *card)
5062
948
{
5063
948
  int r = 0;
5064
948
  size_t rbuflen;
5065
948
  u8 *rbuf = NULL;
5066
948
  piv_private_data_t *priv = PIV_DATA(card);
5067
5068
948
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
5069
5070
  /*
5071
   * During piv_card_reader_lock_obtained,
5072
   * we use the discovery object to test if card present, and
5073
   * if PIV AID is active.
5074
   */
5075
948
  if (priv->obj_cache[PIV_OBJ_DISCOVERY].flags & PIV_OBJ_CACHE_NOT_PRESENT) {
5076
0
    r = SC_ERROR_DATA_OBJECT_NOT_FOUND;
5077
0
    goto end;
5078
0
  }
5079
5080
  /* If not valid: read, test,  cache */
5081
948
  if (!(priv->obj_cache[PIV_OBJ_DISCOVERY].flags & PIV_OBJ_CACHE_VALID)) {
5082
904
    r = piv_process_discovery(card);
5083
904
  } else {
5084
    /* if already in cache,force read */
5085
44
    rbuflen = 1;
5086
44
    r = piv_get_data(card, PIV_OBJ_DISCOVERY, &rbuf, &rbuflen);
5087
    /* if same response as last, no need to parse */
5088
44
    if (r == 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == 0)
5089
0
      goto end;
5090
5091
44
    if (r >= 0 && priv->obj_cache[PIV_OBJ_DISCOVERY].obj_len == rbuflen &&
5092
23
        priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data &&
5093
23
        !memcmp(rbuf, priv->obj_cache[PIV_OBJ_DISCOVERY].obj_data, rbuflen)) {
5094
13
      goto end;
5095
13
    }
5096
    /* This should not happen  bad card */
5097
31
    sc_log(card->ctx, "Discovery not the same as previously read object");
5098
31
    r = SC_ERROR_CORRUPTED_DATA;
5099
31
    goto end;
5100
44
  }
5101
5102
948
end:
5103
948
  free(rbuf);
5104
948
  LOG_FUNC_RETURN(card->ctx, r);
5105
948
}
5106
5107
/*
5108
 * The history object lists what retired keys and certs are on the card
5109
 * or listed in the offCardCertURL. The user will need to download the
5110
 * the offCardURL file.
5111
 * If the offCardCertURL is not cached by the user it will not be used.
5112
 */
5113
static int
5114
piv_process_history(sc_card_t *card)
5115
673
{
5116
673
  piv_private_data_t *priv = PIV_DATA(card);
5117
673
  int r;
5118
673
  int i, tmplen, tmplen2, tmplen3;
5119
673
  int enumtag;
5120
673
  u8 *rbuf = NULL;
5121
673
  size_t rbuflen = 0;
5122
673
  const u8 *body;
5123
673
  size_t bodylen;
5124
673
  const u8 *num;
5125
673
  size_t numlen;
5126
673
  const u8 *url = NULL;
5127
673
  size_t urllen;
5128
673
  u8 *ocfhfbuf = NULL;
5129
673
  unsigned int cla_out, tag_out;
5130
673
  size_t ocfhflen;
5131
673
  const u8 *seq;
5132
673
  const u8 *seqtag;
5133
673
  size_t seqlen;
5134
673
  const u8 *keyref;
5135
673
  size_t keyreflen;
5136
673
  const u8 *cert;
5137
673
  size_t certlen;
5138
673
  size_t certobjlen, i2;
5139
673
  u8 *certobj;
5140
673
  u8 *cp;
5141
5142
673
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
5143
5144
673
  r = piv_get_cached_data(card, PIV_OBJ_HISTORY, &rbuf, &rbuflen);
5145
673
  if (r == SC_ERROR_FILE_NOT_FOUND)
5146
96
    r = 0; /* OK if not found */
5147
673
  if (r <= 0) {
5148
550
    priv->obj_cache[PIV_OBJ_HISTORY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
5149
550
    goto err; /* no file, must be pre 800-73-3 card and not on card */
5150
550
  }
5151
5152
  /* the object is now cached, see what we have */
5153
123
  if (rbuflen != 0) {
5154
123
    body = rbuf;
5155
123
    if ((r = sc_asn1_read_tag(&body, rbuflen, &cla_out, &tag_out, &bodylen)) != SC_SUCCESS ||
5156
123
        ((cla_out << 24 | tag_out) != piv_objects[PIV_OBJ_HISTORY].resp_tag)) {
5157
0
      sc_log(card->ctx, "DER problem %d", r);
5158
0
      r = SC_ERROR_INVALID_ASN1_OBJECT;
5159
0
      goto err;
5160
0
    }
5161
5162
123
    if (body != NULL && bodylen != 0) {
5163
116
      numlen = 0;
5164
116
      num = sc_asn1_find_tag(card->ctx, body, bodylen, 0xC1, &numlen);
5165
116
      if (num) {
5166
36
        if (numlen != 1 || *num > PIV_OBJ_RETIRED_X509_20 - PIV_OBJ_RETIRED_X509_1 + 1) {
5167
2
          r = SC_ERROR_INVALID_ASN1_OBJECT;
5168
2
          goto err;
5169
2
        }
5170
5171
34
        priv->keysWithOnCardCerts = *num;
5172
34
      }
5173
5174
114
      numlen = 0;
5175
114
      num = sc_asn1_find_tag(card->ctx, body, bodylen, 0xC2, &numlen);
5176
114
      if (num) {
5177
3
        if (numlen != 1 || *num > PIV_OBJ_RETIRED_X509_20 - PIV_OBJ_RETIRED_X509_1 + 1) {
5178
2
          r = SC_ERROR_INVALID_ASN1_OBJECT;
5179
2
          goto err;
5180
2
        }
5181
5182
1
        priv->keysWithOffCardCerts = *num;
5183
1
      }
5184
5185
112
      url = sc_asn1_find_tag(card->ctx, body, bodylen, 0xF3, &urllen);
5186
112
      if (url) {
5187
69
        if (urllen > 118) {
5188
0
          r = SC_ERROR_INVALID_ASN1_OBJECT;
5189
0
          goto err;
5190
0
        }
5191
69
        priv->offCardCertURL = calloc(1, urllen + 1);
5192
69
        if (priv->offCardCertURL == NULL)
5193
69
          LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
5194
69
        memcpy(priv->offCardCertURL, url, urllen);
5195
69
      }
5196
112
    } else {
5197
7
      sc_log(card->ctx, "Problem with History object\n");
5198
7
      r = SC_SUCCESS; /* OK if not found */
5199
7
      goto err;
5200
7
    }
5201
123
  }
5202
112
  sc_log(card->ctx, "History on=%d off=%d URL=%s",
5203
112
      priv->keysWithOnCardCerts, priv->keysWithOffCardCerts,
5204
112
      priv->offCardCertURL ? priv->offCardCertURL : "NONE");
5205
5206
  /* now mark what objects are on the card */
5207
641
  for (i = 0; i < priv->keysWithOnCardCerts; i++)
5208
529
    priv->obj_cache[PIV_OBJ_RETIRED_X509_1 + i].flags &= ~PIV_OBJ_CACHE_NOT_PRESENT;
5209
5210
  /*
5211
   * If user has gotten copy of the file from the offCardCertsURL,
5212
   * we will read in and add the certs to the cache as listed on
5213
   * the card. some of the certs may be on the card as well.
5214
   *
5215
   * Get file name from url. verify that the filename is valid
5216
   * The URL ends in a SHA-256 string. We will use this as the filename
5217
   * in the directory used for the  PKCS15 cache
5218
   * "http://" <DNS name> "/" <ASCII-HEX encoded SHA-256 hash of OffCardKeyHistoryFile>
5219
   */
5220
5221
112
  r = 0;
5222
112
  if (priv->offCardCertURL) {
5223
69
    char *fp;
5224
69
    char filename[PATH_MAX];
5225
5226
69
    if (strncmp("http://", priv->offCardCertURL, 7)) {
5227
68
      r = SC_ERROR_INVALID_DATA;
5228
68
      goto err;
5229
68
    }
5230
    /* find the last /  so we have the filename part */
5231
1
    fp = strrchr(priv->offCardCertURL + 7, '/');
5232
1
    if (fp == NULL) {
5233
1
      r = SC_ERROR_INVALID_DATA;
5234
1
      goto err;
5235
1
    }
5236
0
    fp++;
5237
0
    if (strlen(fp) != 64) { /* ASCII-HEX encoded SHA-256 */
5238
0
      r = SC_ERROR_INVALID_DATA;
5239
0
      goto err;
5240
0
    }
5241
0
    for (i = 0; i < 64; i++) {
5242
0
      if (isxdigit((unsigned char)fp[i]) == 0) {
5243
0
        r = SC_ERROR_INVALID_DATA;
5244
0
        goto err;
5245
0
      }
5246
0
    }
5247
5248
    /* Use the same directory as used for other OpenSC cached items */
5249
0
    r = sc_get_cache_dir(card->ctx, filename, sizeof(filename) - strlen(fp) - 2);
5250
0
    if (r != SC_SUCCESS)
5251
0
      goto err;
5252
#ifdef _WIN32
5253
    strlcat(filename, "\\", PATH_MAX);
5254
#else
5255
0
    strlcat(filename, "/", PATH_MAX);
5256
0
#endif
5257
0
    strlcat(filename, fp, PATH_MAX);
5258
5259
0
    r = piv_read_obj_from_file(card, filename,
5260
0
        &ocfhfbuf, &ocfhflen);
5261
0
    if (r == SC_ERROR_FILE_NOT_FOUND) {
5262
0
      r = 0;
5263
0
      goto err;
5264
0
    }
5265
5266
    /*
5267
     * Its a seq of seq of a key ref and cert
5268
     */
5269
5270
0
    body = ocfhfbuf;
5271
0
    if (sc_asn1_read_tag(&body, ocfhflen, &cla_out, &tag_out, &bodylen) != SC_SUCCESS ||
5272
0
        body == NULL ||
5273
0
        bodylen == 0 ||
5274
0
        (cla_out | tag_out) != 0x30) {
5275
0
      sc_log(card->ctx, "DER problem");
5276
0
      r = SC_ERROR_INVALID_ASN1_OBJECT;
5277
0
      goto err;
5278
0
    }
5279
0
    seq = body;
5280
0
    while (bodylen > 0) {
5281
0
      seqtag = seq;
5282
0
      if (sc_asn1_read_tag(&seq, bodylen, &cla_out, &tag_out, &seqlen) != SC_SUCCESS ||
5283
0
          seq == 0 ||
5284
0
          seqlen == 0 ||
5285
0
          (cla_out | tag_out) != 0x30) {
5286
0
        sc_log(card->ctx, "DER problem");
5287
0
        r = SC_ERROR_INVALID_ASN1_OBJECT;
5288
0
        goto err;
5289
0
      }
5290
0
      keyref = sc_asn1_find_tag(card->ctx, seq, seqlen, 0x04, &keyreflen);
5291
0
      if (!keyref || keyreflen != 1 ||
5292
0
          (*keyref < 0x82 || *keyref > 0x95)) {
5293
0
        sc_log(card->ctx, "DER problem");
5294
0
        r = SC_ERROR_INVALID_ASN1_OBJECT;
5295
0
        goto err;
5296
0
      }
5297
0
      cert = keyref + keyreflen;
5298
0
      certlen = seqlen - (cert - seq);
5299
5300
0
      enumtag = PIV_OBJ_RETIRED_X509_1 + *keyref - 0x82;
5301
      /* now add the cert like another object */
5302
5303
0
      if ((tmplen = sc_asn1_put_tag(0x70, NULL, certlen, NULL, 0, NULL)) <= 0 ||
5304
0
          (tmplen2 = sc_asn1_put_tag(0x71, NULL, 1, NULL, 0, NULL)) <= 0 ||
5305
0
          (tmplen3 = sc_asn1_put_tag(0xFE, NULL, 0, NULL, 0, NULL)) <= 0) {
5306
0
        r = SC_ERROR_INVALID_ASN1_OBJECT;
5307
0
        goto err;
5308
0
      }
5309
0
      i2 = tmplen + tmplen2 + tmplen3;
5310
0
      tmplen = sc_asn1_put_tag(0x53, NULL, i2, NULL, 0, NULL);
5311
0
      if (tmplen <= 0) {
5312
0
        r = SC_ERROR_INVALID_ASN1_OBJECT;
5313
0
        goto err;
5314
0
      }
5315
5316
0
      certobjlen = tmplen;
5317
0
      certobj = malloc(certobjlen);
5318
0
      if (certobj == NULL) {
5319
0
        r = SC_ERROR_OUT_OF_MEMORY;
5320
0
        goto err;
5321
0
      }
5322
0
      cp = certobj;
5323
0
      if ((r = sc_asn1_put_tag(0x53, NULL, i2, cp, certobjlen, &cp)) != SC_SUCCESS ||
5324
0
          (r = sc_asn1_put_tag(0x70, cert, certlen, cp, certobjlen - (cp - certobj), &cp)) != SC_SUCCESS ||
5325
0
          (r = sc_asn1_put_tag(0x71, NULL, 1, cp, certobjlen - (cp - certobj), &cp)) != SC_SUCCESS) {
5326
0
        goto err;
5327
0
      }
5328
0
      *cp++ = 0x00;
5329
0
      r = sc_asn1_put_tag(0xFE, NULL, 0, cp, certobjlen - (cp - certobj), &cp);
5330
0
      if (r != SC_SUCCESS) {
5331
0
        goto err;
5332
0
      }
5333
5334
0
      priv->obj_cache[enumtag].obj_data = certobj;
5335
0
      priv->obj_cache[enumtag].obj_len = certobjlen;
5336
0
      priv->obj_cache[enumtag].flags |= PIV_OBJ_CACHE_VALID;
5337
0
      priv->obj_cache[enumtag].flags &= ~PIV_OBJ_CACHE_NOT_PRESENT;
5338
5339
0
      r = piv_cache_internal_data(card, enumtag);
5340
0
      sc_log(card->ctx, "got internal r=%d", r);
5341
5342
0
      sc_log(card->ctx,
5343
0
          "Added from off card file #%d %p:%" SC_FORMAT_LEN_SIZE_T "u 0x%02X",
5344
0
          enumtag,
5345
0
          priv->obj_cache[enumtag].obj_data,
5346
0
          priv->obj_cache[enumtag].obj_len, *keyref);
5347
5348
0
      bodylen -= (seqlen + seq - seqtag);
5349
0
      seq += seqlen;
5350
0
    }
5351
0
  }
5352
673
err:
5353
673
  if (ocfhfbuf)
5354
0
    free(ocfhfbuf);
5355
673
  LOG_FUNC_RETURN(card->ctx, r);
5356
673
}
5357
5358
static int
5359
piv_obj_cache_free_entry(sc_card_t *card, int enumtag, int flags)
5360
292k
{
5361
292k
  piv_private_data_t *priv = PIV_DATA(card);
5362
5363
292k
  if (priv->obj_cache[enumtag].obj_data)
5364
868
    free(priv->obj_cache[enumtag].obj_data);
5365
292k
  priv->obj_cache[enumtag].obj_data = NULL;
5366
292k
  priv->obj_cache[enumtag].obj_len = 0;
5367
5368
292k
  if (priv->obj_cache[enumtag].internal_obj_data)
5369
408
    free(priv->obj_cache[enumtag].internal_obj_data);
5370
292k
  priv->obj_cache[enumtag].internal_obj_data = NULL;
5371
292k
  priv->obj_cache[enumtag].internal_obj_len = 0;
5372
292k
  priv->obj_cache[enumtag].flags = flags;
5373
5374
292k
  return SC_SUCCESS;
5375
292k
}
5376
5377
static int
5378
piv_finish(sc_card_t *card)
5379
9.04k
{
5380
9.04k
  piv_private_data_t *priv = PIV_DATA(card);
5381
9.04k
  int i;
5382
5383
9.04k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
5384
9.04k
  if (priv) {
5385
4.85k
    if (priv->context_specific) {
5386
2
      sc_log(card->ctx, "Clearing CONTEXT_SPECIFIC lock");
5387
2
      priv->context_specific = 0;
5388
2
      sc_unlock(card);
5389
2
    }
5390
4.85k
    free(priv->aid_der.value);
5391
4.85k
    free(priv->al_label);
5392
4.85k
    if (priv->w_buf)
5393
0
      free(priv->w_buf);
5394
4.85k
    if (priv->offCardCertURL)
5395
69
      free(priv->offCardCertURL);
5396
296k
    for (i = 0; i < PIV_OBJ_LAST_ENUM - 1; i++) {
5397
291k
      piv_obj_cache_free_entry(card, i, 0);
5398
291k
    }
5399
#ifdef ENABLE_PIV_SM
5400
    piv_clear_cvc_content(&priv->sm_cvc);
5401
    piv_clear_cvc_content(&priv->sm_in_cvc);
5402
    piv_clear_sm_session(&priv->sm_session);
5403
#endif /* ENABLE_PIV_SM */
5404
5405
4.85k
    free(priv);
5406
4.85k
    card->drv_data = NULL; /* priv */
5407
4.85k
  }
5408
9.04k
  return 0;
5409
9.04k
}
5410
5411
static int
5412
piv_match_card(sc_card_t *card)
5413
4.85k
{
5414
4.85k
  int r = 0;
5415
5416
4.85k
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d\n", card->type);
5417
  /* piv_match_card may be called with card->type, set by opensc.conf */
5418
  /* user provided card type must be one we know */
5419
4.85k
  switch (card->type) {
5420
4.85k
  case -1:
5421
4.85k
  case SC_CARD_TYPE_PIV_II_BASE:
5422
4.85k
  case SC_CARD_TYPE_PIV_II_GENERIC:
5423
4.85k
  case SC_CARD_TYPE_PIV_II_HIST:
5424
4.85k
  case SC_CARD_TYPE_PIV_II_NEO:
5425
4.85k
  case SC_CARD_TYPE_PIV_II_YUBIKEY4:
5426
4.85k
  case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
5427
4.85k
  case SC_CARD_TYPE_PIV_II_GI_DE:
5428
4.85k
  case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
5429
4.85k
  case SC_CARD_TYPE_PIV_II_GEMALTO:
5430
4.85k
  case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
5431
4.85k
  case SC_CARD_TYPE_PIV_II_OBERTHUR:
5432
4.85k
  case SC_CARD_TYPE_PIV_II_PIVKEY:
5433
4.85k
  case SC_CARD_TYPE_PIV_II_SWISSBIT:
5434
4.85k
  case SC_CARD_TYPE_PIV_II_800_73_4:
5435
4.85k
  case SC_CARD_TYPE_PIV_II_NITROKEY:
5436
4.85k
  case SC_CARD_TYPE_PIV_II_TOKEN2:
5437
4.85k
  case SC_CARD_TYPE_PIV_II_PIVAPPLET:
5438
4.85k
    break;
5439
0
  default:
5440
0
    return 0; /* can not handle the card */
5441
4.85k
  }
5442
5443
4.85k
  r = sc_lock(card);
5444
4.85k
  if (r < 0)
5445
0
    return 0;
5446
  /* its one we know, or we can test for it in piv_init */
5447
4.85k
  r = piv_match_card_continued(card);
5448
4.85k
  sc_unlock(card);
5449
5450
4.85k
  if (r < 0 || !card->drv_data) {
5451
    /* clean up what we left in card */
5452
4.18k
    piv_finish(card);
5453
4.18k
    return 0; /* match failed */
5454
4.18k
  }
5455
5456
673
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r:%d\n", card->type, r);
5457
673
  return 1; /* matched */
5458
4.85k
}
5459
5460
static int
5461
piv_match_card_continued(sc_card_t *card)
5462
4.85k
{
5463
4.85k
  int i, r = 0, r2 = 0;
5464
4.85k
  int type = -1;
5465
4.85k
  piv_private_data_t *priv = NULL;
5466
4.85k
  int saved_type = card->type;
5467
4.85k
  sc_apdu_t apdu;
5468
4.85k
  u8 yubico_version_buf[3] = {0};
5469
5470
  /* piv_match_card may be called with card->type, set by opensc.conf */
5471
  /* User provided card type must be one we know */
5472
5473
4.85k
  switch (card->type) {
5474
4.85k
  case -1:
5475
4.85k
  case SC_CARD_TYPE_PIV_II_BASE:
5476
4.85k
  case SC_CARD_TYPE_PIV_II_GENERIC:
5477
4.85k
  case SC_CARD_TYPE_PIV_II_HIST:
5478
4.85k
  case SC_CARD_TYPE_PIV_II_NEO:
5479
4.85k
  case SC_CARD_TYPE_PIV_II_YUBIKEY4:
5480
4.85k
  case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
5481
4.85k
  case SC_CARD_TYPE_PIV_II_GI_DE:
5482
4.85k
  case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
5483
4.85k
  case SC_CARD_TYPE_PIV_II_GEMALTO:
5484
4.85k
  case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
5485
4.85k
  case SC_CARD_TYPE_PIV_II_OBERTHUR:
5486
4.85k
  case SC_CARD_TYPE_PIV_II_PIVKEY:
5487
4.85k
  case SC_CARD_TYPE_PIV_II_SWISSBIT:
5488
4.85k
  case SC_CARD_TYPE_PIV_II_800_73_4:
5489
4.85k
  case SC_CARD_TYPE_PIV_II_NITROKEY:
5490
4.85k
  case SC_CARD_TYPE_PIV_II_TOKEN2:
5491
4.85k
  case SC_CARD_TYPE_PIV_II_PIVAPPLET:
5492
4.85k
    type = card->type;
5493
4.85k
    break;
5494
0
  default:
5495
0
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_CARD);
5496
4.85k
  }
5497
4.85k
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r);
5498
4.85k
  if (type == -1) {
5499
    /*
5500
     * Try to identify card by ATR or historical data in ATR
5501
     * currently all PIV card will respond to piv_find_aid
5502
     * the same. But in future may need to know card type first,
5503
     * so do it here.
5504
     */
5505
5506
4.85k
    if (card->reader->atr_info.hist_bytes != NULL) {
5507
1.16k
      if (card->reader->atr_info.hist_bytes_len == 8 &&
5508
102
          !(memcmp(card->reader->atr_info.hist_bytes, "Yubikey4", 8))) {
5509
28
        type = SC_CARD_TYPE_PIV_II_YUBIKEY4;
5510
1.13k
      } else if (card->reader->atr_info.hist_bytes_len >= 7 &&
5511
704
          !(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) {
5512
95
        type = SC_CARD_TYPE_PIV_II_NEO;
5513
1.04k
      } else if (card->reader->atr_info.hist_bytes_len >= 6 &&
5514
652
          !(memcmp(card->reader->atr_info.hist_bytes, "PIVKEY", 6))) {
5515
27
        type = SC_CARD_TYPE_PIV_II_PIVKEY;
5516
1.01k
      } else if (card->reader->atr_info.hist_bytes_len >= 6 &&
5517
625
          !(memcmp(card->reader->atr_info.hist_bytes, (u8 *)"TK\x00PIV", 6))) {
5518
8
        type = SC_CARD_TYPE_PIV_II_TOKEN2;
5519
8
      }
5520
      /* look for TLV historic data */
5521
1.00k
      else if (card->reader->atr_info.hist_bytes_len > 0 &&
5522
994
          card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */
5523
235
        size_t datalen;
5524
235
        const u8 *data;
5525
5526
        /* look for card issuer's data:  tag 5X where X is datalen */
5527
235
        if ((data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1,
5528
235
                 card->reader->atr_info.hist_bytes_len - 1, 0x50, &datalen))) {
5529
129
          if (datalen >= 8 && !(memcmp(data, "Nitrokey", 8))) { /* first 8 are Nitrokey */
5530
16
            type = SC_CARD_TYPE_PIV_II_NITROKEY;
5531
113
          } else if (datalen == 7 && !(memcmp(data, "YubiKey", 7))) {
5532
70
            type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4  really 5 */
5533
70
          }
5534
          /* Yubikey 5 NFC ATR using ACR122 contactless reader does not match
5535
           * https://developers.yubico.com/PIV/Introduction/Yubico_extensions.html
5536
           * On Windows 10, using Omnikey 5021, the ATR is correct
5537
           * will look at only 6 bytes that do match
5538
           */
5539
43
          else if (datalen == 7 && !(memcmp(data, "YubiKe", 6))) {
5540
21
            type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4 really 5 */
5541
21
          }
5542
129
        } else if ((data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1,
5543
106
                  card->reader->atr_info.hist_bytes_len - 1, 0xF0, &datalen))) {
5544
49
          int k;
5545
5546
144
          for (k = 0; piv_aids[k].len_long != 0; k++) {
5547
97
            if (datalen == piv_aids[k].len_long &&
5548
83
                !memcmp(data, piv_aids[k].value, datalen)) {
5549
2
              type = SC_CARD_TYPE_PIV_II_HIST;
5550
2
              break;
5551
2
            }
5552
97
          }
5553
49
        }
5554
235
      }
5555
1.16k
    }
5556
5557
4.85k
    sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r);
5558
5559
4.85k
    if (type == -1) {
5560
      /* use known ATRs  which changes the type */
5561
4.59k
      i = _sc_match_atr(card, piv_atrs, &type);
5562
4.59k
      if (i < 0)
5563
4.58k
        type = SC_CARD_TYPE_PIV_II_BASE; /* May be some newer unknown card including CAC or PIV-like card */
5564
4.59k
    }
5565
4.85k
  }
5566
5567
4.85k
  card->type = type;
5568
5569
  /* we either found via ATR historic bytes or ATR directly */
5570
4.85k
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r);
5571
5572
  /* allocate and init basic fields */
5573
4.85k
  priv = calloc(1, sizeof(piv_private_data_t));
5574
5575
4.85k
  if (!priv)
5576
4.85k
    LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
5577
5578
4.85k
  card->drv_data = priv; /* will free if no match, or pass on to piv_init */
5579
  /*
5580
   * Largest object defined in NIST sp800-73-3 and sp800-73-4 is 12710 bytes
5581
   * If for some reason future cards have larger objects, this value needs to
5582
   * be increased here.
5583
   */
5584
4.85k
  priv->max_object_size = MAX_FILE_SIZE - 256; /* fix SM apdu resplen issue */
5585
4.85k
  priv->selected_obj = -1;
5586
4.85k
  priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */
5587
4.85k
  priv->logged_in = SC_PIN_STATE_UNKNOWN;
5588
4.85k
  priv->pstate = PIV_STATE_MATCH;
5589
5590
#ifdef ENABLE_PIV_SM
5591
  memset(&card->sm_ctx, 0, sizeof card->sm_ctx);
5592
  card->sm_ctx.ops.open = piv_sm_open;
5593
  card->sm_ctx.ops.get_sm_apdu = piv_get_sm_apdu;
5594
  card->sm_ctx.ops.free_sm_apdu = piv_free_sm_apdu;
5595
  card->sm_ctx.ops.close = piv_sm_close;
5596
#endif /* ENABLE_PIV_SM */
5597
5598
  /* See if contactless  or run as virtual card */
5599
  /* PivApplet in .github/test_piv.sh for example */
5600
4.85k
  if (card->reader->atr.len >= 4 &&
5601
1.28k
      card->reader->atr.value[0] == 0x3b &&
5602
1.19k
      (card->reader->atr.value[1] & 0xF0) == 0x80 &&
5603
73
      card->reader->atr.value[2] == 0x80 &&
5604
45
      card->reader->atr.value[3] == 0x01) {
5605
29
    priv->init_flags |= PIV_INIT_CONTACTLESS;
5606
29
  }
5607
5608
296k
  for (i = 0; i < PIV_OBJ_LAST_ENUM - 1; i++)
5609
291k
    if (piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT)
5610
97.1k
      priv->obj_cache[i].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
5611
  /*
5612
   * Detect if active AID is PIV. NIST 800-73 says only one PIV application per card
5613
   * and PIV must be the default application.
5614
   * Try to avoid doing a select_aid and losing the login state on some cards.
5615
   * We may get interference on some cards by other drivers trying SELECT_AID before
5616
   * we get to see if PIV application is still active. Putting PIV driver first might help.
5617
   *
5618
   * Discovery Object introduced in 800-73-3 so will return OK if found and PIV applet active.
5619
   * Will fail with SC_ERROR_FILE_NOT_FOUND if 800-73-3 and no Discovery object.
5620
   * But some other card could also return SC_ERROR_FILE_NOT_FOUND.
5621
   * Will fail for other reasons if wrong applet is selected or bad PIV implementation.
5622
   */
5623
5624
  /*
5625
   * if ATR matched or user forced card type
5626
   * test if PIV is active applet without using AID If fails try AID
5627
   */
5628
5629
4.85k
  if (card->type > SC_CARD_TYPE_PIV_II_BASE &&
5630
273
      !(priv->init_flags & PIV_INIT_CONTACTLESS)) {
5631
271
    r = piv_find_discovery(card);
5632
271
    if (r < 0) {
5633
237
      piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, 0); /* don't cache  on failure */
5634
237
      r = piv_find_aid(card);
5635
237
      LOG_TEST_GOTO_ERR(card->ctx, r, "Not a PIV card");
5636
237
    }
5637
4.58k
  } else {
5638
    /* piv_find_aid saves al_label from response */
5639
4.58k
    r = piv_find_aid(card);
5640
4.58k
    LOG_TEST_GOTO_ERR(card->ctx, r, "Not a PIV card");
5641
4.58k
  }
5642
5643
  /* Know to be PIV card but not the type */
5644
5645
  /* If card type still unknown, see if Application Label is known and set card->type */
5646
673
  if (priv->al_label && priv->al_labellen) {
5647
12
    switch (card->type) {
5648
11
    case SC_CARD_TYPE_PIV_II_BASE:
5649
11
    case SC_CARD_TYPE_PIV_II_GENERIC:
5650
21
      for (i = 0; al_map[i].al_label; i++) {
5651
11
        if ((priv->al_labellen >= al_map[i].al_labellen) &&
5652
9
            (!memcmp(priv->al_label, al_map[i].al_label, al_map[i].al_labellen))) {
5653
1
          sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "AL match i:%d type:%d", i, al_map[i].al_type);
5654
1
          card->type = al_map[i].al_type;
5655
1
          break;
5656
1
        }
5657
11
      }
5658
11
      break;
5659
12
    }
5660
12
  }
5661
5662
673
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d  CI:%08x r:%d AI:%08x\n",
5663
673
      card->type, priv->card_issues, r, priv->alg_ids);
5664
5665
  /*
5666
   * Assumes all Yubikey/Nitrokey/Token2/PivApplet cards are all "Yubico like"
5667
   * via ATR, ATR Historic bytes or Application Label
5668
   * Will also check if BASE cards are Yubikey like card and return a version number
5669
   * SC_CARD_TYPE_PIV_II_GENERIC can be set by user to not test for Yubico version
5670
   */
5671
673
  switch (card->type) {
5672
79
  case SC_CARD_TYPE_PIV_II_NEO:
5673
165
  case SC_CARD_TYPE_PIV_II_YUBIKEY4:
5674
180
  case SC_CARD_TYPE_PIV_II_NITROKEY:
5675
183
  case SC_CARD_TYPE_PIV_II_TOKEN2:
5676
184
  case SC_CARD_TYPE_PIV_II_PIVAPPLET:
5677
184
  case SC_CARD_TYPE_PIV_II_GENERIC:
5678
667
  case SC_CARD_TYPE_PIV_II_BASE: /* unknown PIV card */
5679
667
    sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xFD, 0x00, 0x00);
5680
667
    apdu.lc = 0;
5681
667
    apdu.data = NULL;
5682
667
    apdu.datalen = 0;
5683
667
    apdu.resp = yubico_version_buf;
5684
667
    apdu.resplen = sizeof(yubico_version_buf);
5685
667
    apdu.le = apdu.resplen;
5686
667
    r2 = sc_transmit_apdu(card, &apdu); /* if not supported yubico_version == 0 */
5687
667
    if (apdu.resplen == 3) {
5688
347
      priv->yubico_version = (yubico_version_buf[0] << 16) | (yubico_version_buf[1] << 8) | yubico_version_buf[2];
5689
347
      sc_log(card->ctx, "Yubikey version test card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version);
5690
347
    }
5691
667
    break;
5692
673
  }
5693
5694
673
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5695
673
      card->type, r2, priv->card_issues, r, priv->alg_ids);
5696
5697
  /* We now know PIV AID is active, test CCC object. 800-73-* say CCC is required */
5698
  /* CCC not readable over contactless, unless using VCI. but dont need CCC for SC_CARD_TYPE_PIV_II_800_73_4 */
5699
673
  switch (card->type) {
5700
  /*
5701
   * For cards that may also be CAC, try and read the CCC
5702
   * CCC is required and all Dual PIV/CAC will have a CCC
5703
   * Currently Dual PIV/CAC are based on NIST 800-73-1 which does not have Discovery or History
5704
   */
5705
483
  case SC_CARD_TYPE_PIV_II_BASE: /* i.e. really dont know what this is */
5706
483
  case SC_CARD_TYPE_PIV_II_GENERIC:
5707
484
  case SC_CARD_TYPE_PIV_II_HIST:
5708
484
  case SC_CARD_TYPE_PIV_II_GI_DE:
5709
485
  case SC_CARD_TYPE_PIV_II_GEMALTO:
5710
487
  case SC_CARD_TYPE_PIV_II_OBERTHUR:
5711
487
    r2 = piv_process_ccc(card);
5712
487
    sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5713
487
        card->type, r2, priv->card_issues, r, priv->alg_ids);
5714
    /* Ignore any error. */
5715
    /* If CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */
5716
487
    if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) {
5717
6
      switch (card->type) {
5718
6
      case SC_CARD_TYPE_PIV_II_BASE:
5719
6
      case SC_CARD_TYPE_PIV_II_GENERIC:
5720
6
      case SC_CARD_TYPE_PIV_II_HIST:
5721
6
      case SC_CARD_TYPE_PIV_II_GI_DE:
5722
6
        card->type = SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC;
5723
6
        priv->card_issues |= CI_DISCOVERY_USELESS;
5724
6
        priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
5725
6
        break;
5726
0
      case SC_CARD_TYPE_PIV_II_GEMALTO:
5727
0
        card->type = SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC;
5728
0
        priv->card_issues |= CI_DISCOVERY_USELESS;
5729
0
        priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
5730
0
        break;
5731
0
      case SC_CARD_TYPE_PIV_II_OBERTHUR:
5732
0
        card->type = SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC;
5733
0
        priv->card_issues |= CI_DISCOVERY_USELESS;
5734
0
        priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
5735
0
        break;
5736
6
      }
5737
6
    }
5738
487
    break;
5739
5740
487
  case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
5741
0
  case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
5742
0
  case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
5743
0
    priv->card_issues |= CI_DISCOVERY_USELESS;
5744
0
    priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
5745
0
    break;
5746
673
  }
5747
673
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5748
673
      card->type, r2, priv->card_issues, r, priv->alg_ids);
5749
5750
  /* If contactless or run as virtual card try to get alg refs from AC entries in response to SELECT AID */
5751
673
  if (!(priv->init_flags & PIV_INIT_AID_PARSED) && priv->init_flags & PIV_INIT_CONTACTLESS) {
5752
0
    r2 = piv_find_aid(card);
5753
0
  }
5754
5755
  /* Read AID if needed for these cards types */
5756
673
  if (!(priv->init_flags & PIV_INIT_AID_PARSED)) {
5757
34
    switch (card->type) {
5758
0
    case SC_CARD_TYPE_PIV_II_BASE:
5759
0
    case SC_CARD_TYPE_PIV_II_GENERIC:
5760
0
    case SC_CARD_TYPE_PIV_II_800_73_4:
5761
0
    case SC_CARD_TYPE_PIV_II_NITROKEY:
5762
1
    case SC_CARD_TYPE_PIV_II_TOKEN2:
5763
1
    case SC_CARD_TYPE_PIV_II_PIVAPPLET:
5764
1
      r2 = piv_find_aid(card);
5765
34
    }
5766
34
  }
5767
5768
673
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5769
673
      card->type, r2, priv->card_issues, r, priv->alg_ids);
5770
5771
  /* if card did not specify any of the NIST basic alg_ids add them */
5772
673
  if ((priv->alg_ids & AI_NIST) == 0) {
5773
671
    priv->alg_ids |= AI_NIST;
5774
671
  }
5775
5776
  /* If unknown card has 800-73-4 features, it must be based on 800-73-4 or above */
5777
673
  switch (card->type) {
5778
477
  case SC_CARD_TYPE_PIV_II_BASE:
5779
477
  case SC_CARD_TYPE_PIV_II_GENERIC:
5780
477
    if (priv->init_flags & PIV_INIT_AID_AC_SM) {
5781
0
      card->type = SC_CARD_TYPE_PIV_II_800_73_4;
5782
0
    }
5783
5784
#ifdef ENABLE_PIV_SM
5785
    /* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */
5786
    if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) {
5787
      card->type = SC_CARD_TYPE_PIV_II_800_73_4;
5788
    }
5789
#endif
5790
477
    break;
5791
673
  }
5792
5793
673
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5794
673
      card->type, r2, priv->card_issues, r, priv->alg_ids);
5795
5796
  /*
5797
   * Set card_issues flags based card->type and version numbers if available.
5798
   *
5799
   * YubiKey NEO, Yubikey 4 and other devices with PIV applets, have compliance
5800
   * issues with the NIST 800-73-3 specs. The OpenSC developers do not have
5801
   * access to all the different devices or versions of the devices.
5802
   * Vendor and user input is welcome on any compliance issues.
5803
   *
5804
   * For the Yubico devices The assumption is also made that if a bug is
5805
   * fixed in a Yubico version that means it is fixed on both NEO and Yubikey 4.
5806
   *
5807
   * The flags CI_CANT_USE_GETDATA_FOR_STATE and CI_DISCOVERY_USELESS
5808
   * may be set earlier or later then in the following code.
5809
   */
5810
5811
673
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5812
673
      card->type, r2, priv->card_issues, r, priv->alg_ids);
5813
673
  switch (card->type) {
5814
79
  case SC_CARD_TYPE_PIV_II_NEO:
5815
79
    priv->card_issues |= CI_NO_EC384 |
5816
79
             CI_VERIFY_630X |
5817
79
             CI_OTHER_AID_LOSE_STATE |
5818
79
             CI_LEAKS_FILE_NOT_FOUND |
5819
79
             CI_NFC_EXPOSE_TOO_MUCH;
5820
79
    if (priv->yubico_version < 0x00040302)
5821
32
      priv->card_issues |= CI_VERIFY_LC0_FAIL;
5822
79
    break;
5823
5824
86
  case SC_CARD_TYPE_PIV_II_YUBIKEY4:
5825
87
  case SC_CARD_TYPE_PIV_II_PIVAPPLET:
5826
90
  case SC_CARD_TYPE_PIV_II_TOKEN2:
5827
90
    priv->card_issues |= CI_OTHER_AID_LOSE_STATE |
5828
90
             CI_LEAKS_FILE_NOT_FOUND;
5829
90
    if (priv->yubico_version < 0x00040302)
5830
64
      priv->card_issues |= CI_VERIFY_LC0_FAIL;
5831
90
    if (priv->yubico_version >= 0x00050700) /* Also used by Token2 */
5832
24
      priv->alg_ids |= AI_RSA_4096 | AI_25519;
5833
90
    break;
5834
5835
15
  case SC_CARD_TYPE_PIV_II_NITROKEY:
5836
15
    priv->card_issues |= CI_OTHER_AID_LOSE_STATE;
5837
15
    if (priv->yubico_version >= 0x00010802) /* use for NitroKey too */
5838
9
      priv->alg_ids |= AI_RSA_4096;
5839
15
    break;
5840
5841
0
  case SC_CARD_TYPE_PIV_II_GI_DE:
5842
2
  case SC_CARD_TYPE_PIV_II_OBERTHUR:
5843
3
  case SC_CARD_TYPE_PIV_II_GEMALTO:
5844
3
  case SC_CARD_TYPE_PIV_II_SWISSBIT:
5845
3
    priv->card_issues |= 0; /* could add others here */
5846
3
    break;
5847
5848
477
  case SC_CARD_TYPE_PIV_II_BASE:
5849
478
  case SC_CARD_TYPE_PIV_II_HIST:
5850
479
  case SC_CARD_TYPE_PIV_II_800_73_4:
5851
479
    priv->card_issues |= 0; /* could add others here */
5852
479
    break;
5853
5854
6
  case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
5855
6
  case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
5856
6
  case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
5857
6
    priv->card_issues |= CI_VERIFY_LC0_FAIL |
5858
6
             CI_PIV_AID_LOSE_STATE |
5859
6
             CI_NO_RANDOM |
5860
6
             CI_OTHER_AID_LOSE_STATE;
5861
6
    break;
5862
5863
0
  case SC_CARD_TYPE_PIV_II_GENERIC:
5864
0
    priv->card_issues |= CI_VERIFY_LC0_FAIL |
5865
0
             CI_OTHER_AID_LOSE_STATE;
5866
0
    break;
5867
5868
1
  case SC_CARD_TYPE_PIV_II_PIVKEY:
5869
1
    priv->card_issues |= CI_VERIFY_LC0_FAIL |
5870
1
             CI_PIV_AID_LOSE_STATE | /* be conservative */
5871
1
             CI_NO_RANDOM;      /* does not have 9B key */
5872
                   /* Discovery object returns 6A 82 so is not on card by default */
5873
1
    break;
5874
5875
0
  default:
5876
0
    priv->card_issues |= CI_VERIFY_LC0_FAIL |
5877
0
             CI_OTHER_AID_LOSE_STATE;
5878
    /* opensc.conf may have it wrong, continue anyway */
5879
0
    sc_log(card->ctx, "Unknown PIV card->type %d", card->type);
5880
0
    card->type = SC_CARD_TYPE_PIV_II_GENERIC;
5881
673
  }
5882
673
  sc_log(card->ctx, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5883
673
      card->type, r2, priv->card_issues, r, priv->alg_ids);
5884
5885
673
  if (!(priv->card_issues & CI_DISCOVERY_USELESS) && !(priv->init_flags & PIV_INIT_DISCOVERY_PARSED)) {
5886
    /*
5887
     * We now know PIV AID is active, test DISCOVERY object again
5888
     * Some PIV don't support DISCOVERY and return
5889
     * SC_ERROR_INCORRECT_PARAMETERS. Any error
5890
     * including SC_ERROR_FILE_NOT_FOUND means we cannot use discovery
5891
     * to test for active AID.
5892
     */
5893
633
    r2 = piv_find_discovery(card);
5894
5895
633
    if (r2 < 0) {
5896
627
      priv->card_issues |= CI_DISCOVERY_USELESS;
5897
627
      piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, PIV_OBJ_CACHE_NOT_PRESENT);
5898
627
    }
5899
633
  }
5900
5901
673
  sc_log(card->ctx, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5902
673
      card->type, r2, priv->card_issues, r, priv->alg_ids);
5903
  /* Matched, caller will use or free priv and sc_lock as needed */
5904
673
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
5905
5906
4.18k
err:
5907
4.18k
  sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH failed card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
5908
4.18k
      card->type, r2, priv->card_issues, r, priv->alg_ids);
5909
  /* don't match. Does not have a PIV applet. */
5910
4.18k
  piv_finish(card);
5911
4.18k
  card->type = saved_type;
5912
4.18k
  LOG_FUNC_RETURN(card->ctx, r);
5913
4.18k
}
5914
5915
static int
5916
piv_init(sc_card_t *card)
5917
673
{
5918
673
  int r = 0;
5919
673
  piv_private_data_t *priv = PIV_DATA(card);
5920
673
  unsigned long flags;
5921
673
  unsigned long flags_eddsa;
5922
673
  unsigned long flags_xeddsa;
5923
673
  unsigned long ext_flags;
5924
5925
673
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
5926
5927
673
  r = sc_lock(card); /* hold until match or init is complete */
5928
673
  LOG_TEST_RET(card->ctx, r, "sc_lock failed");
5929
5930
  /* piv_match_card_continued called from card match should have left card->drv_data */
5931
673
  if (priv == NULL) {
5932
0
    r = piv_match_card_continued(card);
5933
0
    priv = PIV_DATA(card);
5934
0
    if (r < 0 || !priv) {
5935
0
      sc_log(card->ctx, "piv_match_card_continued failed card->type:%d", card->type);
5936
0
      sc_unlock(card);
5937
0
      piv_finish(card);
5938
      /* tell sc_connect_card to try other driver */
5939
0
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_CARD);
5940
0
    }
5941
0
  }
5942
5943
  /* read "card_driver PIV-II" opensc.conf options, and env parameters */
5944
673
  piv_load_options(card);
5945
5946
673
  priv->pstate = PIV_STATE_INIT;
5947
5948
673
  sc_log(card->ctx,
5949
673
      "Max send = %" SC_FORMAT_LEN_SIZE_T "u recv = %" SC_FORMAT_LEN_SIZE_T "u card->type:%d, CI:%08x AI:%08x",
5950
673
      card->max_send_size, card->max_recv_size, card->type, priv->card_issues, priv->alg_ids);
5951
673
  card->cla = 0x00;
5952
673
  if (card->name == NULL)
5953
673
    card->name = card->driver->name;
5954
5955
673
  priv->enumtag = piv_aids[0].enumtag;
5956
5957
  /* PKCS#11 may try to generate session keys, and get confused
5958
   * if SC_ALGORITHM_ONBOARD_KEY_GEN is present
5959
   * piv-tool can still do this, just don't tell PKCS#11
5960
   */
5961
5962
673
  flags = SC_ALGORITHM_RSA_RAW;
5963
5964
673
  if (card->type == SC_CARD_TYPE_PIV_II_SWISSBIT) {
5965
0
    flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;
5966
0
  }
5967
5968
673
  if (priv->alg_ids & AI_RSA_1024)
5969
672
    _sc_card_add_rsa_alg(card, 1024, flags, 0); /* mandatory */
5970
5971
673
  if (priv->alg_ids & AI_RSA_2048)
5972
671
    _sc_card_add_rsa_alg(card, 2048, flags, 0); /* optional */
5973
5974
673
  if (priv->alg_ids & AI_RSA_3072)
5975
672
    _sc_card_add_rsa_alg(card, 3072, flags, 0); /* optional */
5976
5977
673
  if (priv->alg_ids & AI_RSA_4096)
5978
33
    _sc_card_add_rsa_alg(card, 4096, flags, 0); /* non standard */
5979
5980
673
  if (!(priv->card_issues & CI_NO_EC)) {
5981
673
    int i;
5982
673
    flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE;
5983
673
    ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
5984
673
    flags_eddsa = SC_ALGORITHM_EDDSA_RAW;
5985
673
    flags_xeddsa = SC_ALGORITHM_XEDDSA_RAW;
5986
5987
3.36k
    for (i = 0; ec_curves[i].oid.value[0] >= 0; i++) {
5988
2.69k
      if (ec_curves[i].key_type == SC_ALGORITHM_EC) {
5989
1.34k
        if (!(priv->card_issues & CI_NO_EC384 && ec_curves[i].size == 384))
5990
1.26k
          _sc_card_add_ec_alg(card, ec_curves[i].size, flags, ext_flags, &ec_curves[i].oid);
5991
1.34k
      }
5992
5993
1.34k
      else if (priv->alg_ids & AI_25519 && ec_curves[i].key_type == SC_ALGORITHM_EDDSA)
5994
24
        _sc_card_add_eddsa_alg(card, ec_curves[i].size, flags_eddsa, ext_flags, &ec_curves[i].oid);
5995
5996
1.32k
      else if (priv->alg_ids & AI_X25519 && ec_curves[i].key_type == SC_ALGORITHM_XEDDSA)
5997
1
        _sc_card_add_xeddsa_alg(card, ec_curves[i].size, flags_xeddsa, ext_flags, &ec_curves[i].oid);
5998
2.69k
    }
5999
673
  }
6000
6001
673
  if (!(priv->card_issues & CI_NO_RANDOM))
6002
666
    card->caps |= SC_CARD_CAP_RNG;
6003
6004
  /* May turn off SC_CARD_CAP_ISO7816_PIN_INFO later */
6005
673
  card->caps |= SC_CARD_CAP_ISO7816_PIN_INFO;
6006
6007
  /*
6008
   * 800-73-3 cards may have discovery. "piv-like cards may or may not.
6009
   * 800-73-4 with VCI must have it as it has the pin policy needed for VCI .
6010
   */
6011
6012
#ifdef ENABLE_PIV_SM
6013
  /*
6014
   * 800-73-4
6015
   * Response of AID says if SM is supported. Look for Cipher Suite
6016
   */
6017
  if (priv->csID && priv->cs != NULL) {
6018
    /*
6019
     * Main point in SM and VCI is to allow contactless access
6020
     */
6021
    /* Only piv_init and piv_reader_lock_obtained should call piv_sm_open */
6022
6023
    /* If user said PIV_SM_FLAGS_NEVER, dont start SM; implies limited contatless access */
6024
    if (priv->sm_flags & PIV_SM_FLAGS_NEVER) {
6025
      sc_log(card->ctx, "User has requested PIV_SM_FLAGS_NEVER");
6026
      r = SC_SUCCESS; /* Users choice */
6027
6028
    } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) &&
6029
        !(priv->pin_policy & PIV_PP_VCI_IMPL)) {
6030
      sc_log(card->ctx, "Contactless and no card support for VCI");
6031
      r = SC_SUCCESS; /* User should know VCI is not possible with their card; use like 800-73-3 contactless  */
6032
6033
    } else if ((priv->init_flags & PIV_INIT_CONTACTLESS) &&
6034
        !(priv->pin_policy & PIV_PP_VCI_WITHOUT_PC) &&
6035
        (priv->pairing_code[0] == 0x00)) {
6036
      sc_log(card->ctx, "Contactless, pairing_code required and no pairing code");
6037
      r = SC_ERROR_PIN_CODE_INCORRECT; /* User should know they need to set pairing code */
6038
6039
    } else {
6040
      priv->sm_flags |= PIV_SM_FLAGS_DEFER_OPEN; /* tell priv_sm_open, OK to open */
6041
      r = piv_sm_open(card);
6042
      sc_log(card->ctx, "piv_sm_open returned:%d", r);
6043
    }
6044
6045
    /* If failed, and user said PIV_SM_FLAGS_ALWAYS quit */
6046
    if (priv->sm_flags & PIV_SM_FLAGS_ALWAYS && r < 0) {
6047
      sc_log(card->ctx, "User has requested PIV_SM_FLAGS_ALWAYS, SM has failed to start, don't use the card");
6048
      LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_ALLOWED);
6049
    }
6050
6051
    /* user has wrong or no required pairing code */
6052
    if (r == SC_ERROR_PIN_CODE_INCORRECT)
6053
      LOG_FUNC_RETURN(card->ctx, r);
6054
6055
    /* If SM did not start, or is not expected to start, continue on without it */
6056
  }
6057
#endif /* ENABLE_PIV_SM */
6058
6059
  /*
6060
   * 800-73-3 cards may have a history object
6061
   * We want to process it now as this has information on what
6062
   * keys and certs. "piv like" cards may or may not have history
6063
   */
6064
673
  piv_process_history(card);
6065
6066
673
  priv->pstate = PIV_STATE_NORMAL;
6067
673
  sc_unlock(card);
6068
673
  LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
6069
673
}
6070
6071
static int
6072
piv_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
6073
12.2k
{
6074
12.2k
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
6075
6076
12.2k
  int r;
6077
#ifdef ENABLE_PIV_SM
6078
  int i;
6079
#endif
6080
12.2k
  piv_private_data_t *priv = PIV_DATA(card);
6081
6082
12.2k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
6083
6084
  /* may be called before piv_init has allocated priv */
6085
12.2k
  if (priv) {
6086
    /* need to save sw1 and sw2 if trying to determine card_state from pin_cmd */
6087
6088
12.2k
    if (priv->pin_cmd_verify) {
6089
56
      priv->pin_cmd_verify_sw1 = sw1;
6090
56
      priv->pin_cmd_verify_sw2 = sw2;
6091
12.2k
    } else {
6092
      /* a command has completed and it is not verify
6093
       * If we are in a context_specific sequence, unlock
6094
       * This just decrements the extra lock count
6095
       */
6096
12.2k
      if (priv->context_specific) {
6097
9
        sc_log(card->ctx, "Clearing CONTEXT_SPECIFIC lock");
6098
9
        priv->context_specific = 0;
6099
9
        sc_unlock(card);
6100
9
      }
6101
12.2k
    }
6102
6103
12.2k
    if (priv->card_issues & CI_VERIFY_630X) {
6104
6105
      /* Handle the Yubikey NEO or any other PIV card which returns in response to a verify
6106
       * 63 0X rather than 63 CX indicate the number of remaining PIN retries.
6107
       * Perhaps they misread the spec and thought 0xCX meant "clear" or "don't care", not a literal 0xC!
6108
       */
6109
834
      if (priv->pin_cmd_verify && sw1 == 0x63U) {
6110
2
        priv->pin_cmd_verify_sw2 |= 0xC0U; /* make it easier to test in other code */
6111
2
        if ((sw2 & ~0x0fU) == 0x00U) {
6112
1
          sc_log(card->ctx, "Verification failed (remaining tries: %d)", (sw2 & 0x0f));
6113
1
          return SC_ERROR_PIN_CODE_INCORRECT;
6114
          /* this is what the iso_check_sw returns for 63 C0 */
6115
1
        }
6116
2
      }
6117
834
    }
6118
12.2k
  }
6119
#ifdef ENABLE_PIV_SM
6120
  /* Note 6982 is map to SC_ERROR_SM_NO_SESSION_KEYS but iso maps it to SC_ERROR_SECURITY_STATUS_NOT_SATISFIED */
6121
  /* we do this because 6982 could also mean a verify is not allowed over contactless without VCI */
6122
  /* we stashed the sw1 and sw2 above for verify */
6123
  /* Check specific NIST sp800-73-4 SM  errors */
6124
  for (i = 0; piv_sm_errors[i].SWs != 0; i++) {
6125
    if (piv_sm_errors[i].SWs == ((sw1 << 8) | sw2)) {
6126
      sc_log(card->ctx, "%s", piv_sm_errors[i].errorstr);
6127
      return piv_sm_errors[i].errorno;
6128
    }
6129
  }
6130
#endif
6131
12.2k
  r = iso_drv->ops->check_sw(card, sw1, sw2);
6132
12.2k
  return r;
6133
12.2k
}
6134
6135
static int
6136
piv_check_protected_objects(sc_card_t *card)
6137
0
{
6138
0
  int r = 0;
6139
0
  int i;
6140
0
  piv_private_data_t *priv = PIV_DATA(card);
6141
0
  u8 buf[8]; /* tag of 53 with 82 xx xx  will fit in 4 */
6142
0
  u8 *rbuf;
6143
0
  size_t buf_len;
6144
0
  static int protected_objects[] = {PIV_OBJ_PI, PIV_OBJ_CHF, PIV_OBJ_IRIS_IMAGE};
6145
6146
0
  LOG_FUNC_CALLED(card->ctx);
6147
  /*
6148
   * routine only called from piv_pin_cmd after verify lc=0 did not return 90 00
6149
   * We will test for a protected object using GET DATA.
6150
   *
6151
   * Based on observations, of cards using the GET DATA APDU,
6152
   * SC_ERROR_SECURITY_STATUS_NOT_SATISFIED  means the PIN not verified,
6153
   * SC_SUCCESS means PIN has been verified even if it has length 0
6154
   * SC_ERROR_FILE_NOT_FOUND (which is the bug) does not tell us anything
6155
   * about the state of the PIN and we will try the next object.
6156
   *
6157
   * If we can't determine the security state from this process,
6158
   * set card_issues CI_CANT_USE_GETDATA_FOR_STATE
6159
   * and return SC_ERROR_PIN_CODE_INCORRECT
6160
   * The circumvention is to add a dummy Printed Info object in the card.
6161
   * so we will have an object to test.
6162
   *
6163
   * We save the object's number to use in the future.
6164
   *
6165
   */
6166
0
  if (priv->object_test_verify == 0) {
6167
0
    for (i = 0; i < (int)(sizeof(protected_objects) / sizeof(int)); i++) {
6168
0
      buf_len = sizeof(buf);
6169
0
      rbuf = buf;
6170
0
      r = piv_get_data(card, protected_objects[i], &rbuf, &buf_len);
6171
0
      if (r >= 0 || r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
6172
6173
        /* we can use this object next time if needed */
6174
0
        priv->object_test_verify = protected_objects[i];
6175
0
        break;
6176
0
      }
6177
0
    }
6178
0
    if (priv->object_test_verify == 0) {
6179
      /*
6180
       * none of the objects returned acceptable sw1, sw2
6181
       */
6182
0
      sc_log(card->ctx, "No protected objects found, setting CI_CANT_USE_GETDATA_FOR_STATE");
6183
0
      priv->card_issues |= CI_CANT_USE_GETDATA_FOR_STATE;
6184
0
      r = SC_ERROR_PIN_CODE_INCORRECT;
6185
0
    }
6186
0
  } else {
6187
    /* use the one object we found earlier. Test is security status has changed */
6188
0
    buf_len = sizeof(buf);
6189
0
    rbuf = buf;
6190
0
    r = piv_get_data(card, priv->object_test_verify, &rbuf, &buf_len);
6191
0
  }
6192
0
  if (r == SC_ERROR_FILE_NOT_FOUND)
6193
0
    r = SC_ERROR_PIN_CODE_INCORRECT;
6194
0
  else if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
6195
0
    r = SC_ERROR_PIN_CODE_INCORRECT;
6196
0
  else if (r > 0)
6197
0
    r = SC_SUCCESS;
6198
6199
0
  sc_log(card->ctx, "card->type:%d CI:%08x r:%d AI:%08x\n",
6200
0
      card->type, priv->card_issues, r, priv->alg_ids);
6201
0
  LOG_FUNC_RETURN(card->ctx, r);
6202
0
}
6203
6204
static int
6205
piv_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data)
6206
46
{
6207
46
  int r = 0;
6208
46
  piv_private_data_t *priv = PIV_DATA(card);
6209
6210
  /* Extra validation of (new) PIN during a PIN change request, to
6211
   * ensure it's not outside the FIPS 201 4.1.6.1 (numeric only) and
6212
   * FIPS 140-2 (6 character minimum) requirements.
6213
   */
6214
46
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
6215
6216
46
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
6217
46
  sc_log(card->ctx, "piv_pin_cmd tries_left=%d, logged_in=%d", priv->tries_left, priv->logged_in);
6218
46
  if (data->cmd == SC_PIN_CMD_CHANGE) {
6219
0
    size_t i = 0;
6220
0
    if (data->pin2.len < 6) {
6221
0
      return SC_ERROR_INVALID_PIN_LENGTH;
6222
0
    }
6223
0
    for (i = 0; i < data->pin2.len; ++i) {
6224
0
      if (!isdigit(data->pin2.data[i])) {
6225
0
        return SC_ERROR_INVALID_DATA;
6226
0
      }
6227
0
    }
6228
0
  }
6229
6230
46
  priv->pin_cmd_verify_sw1 = 0x00U;
6231
6232
46
  if (data->cmd == SC_PIN_CMD_GET_INFO) { /* fill in what we think it should be */
6233
0
    data->pin1.logged_in = priv->logged_in;
6234
0
    data->pin1.tries_left = priv->tries_left;
6235
6236
    /*
6237
     * If called to check on the login state for a context specific login
6238
     * return not logged in. Needed because of logic in e6f7373ef066
6239
     */
6240
0
    if (data->pin_type == SC_AC_CONTEXT_SPECIFIC) {
6241
0
      data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT;
6242
0
      LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
6243
0
    }
6244
6245
0
    if (priv->logged_in & SC_PIN_STATE_LOGGED_IN) {
6246
      /* Avoid status requests when the user is logged in to handle NIST
6247
       * 800-73-4 Part 2:
6248
       * The PKI cryptographic function (see Table 4b) is protected with
6249
       * a “PIN Always” or “OCC Always” access rule. In other words, the
6250
       * PIN or OCC data must be submitted and verified every time
6251
       * immediately before a digital signature key operation.  This
6252
       * ensures cardholder participation every time the private key is
6253
       * used for digital signature generation */
6254
0
      LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
6255
0
    }
6256
0
  }
6257
6258
  /*
6259
   * If this was for a CKU_CONTEXT_SPECFIC login, lock the card one more time.
6260
   * to avoid any interference from other applications.
6261
   * Sc_unlock will be called at a later time after the next card command
6262
   * that should be a crypto operation. If its not then it is a error by the
6263
   * calling application.
6264
   */
6265
46
  if (data->cmd == SC_PIN_CMD_VERIFY && data->pin_type == SC_AC_CONTEXT_SPECIFIC) {
6266
22
    priv->context_specific = 1;
6267
22
    sc_log(card->ctx, "Starting CONTEXT_SPECIFIC verify");
6268
22
    r = sc_lock(card);
6269
22
    if (r != SC_SUCCESS) {
6270
0
      sc_log(card->ctx, "sc_lock failed");
6271
0
      return r;
6272
0
    }
6273
22
  }
6274
6275
46
  priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */
6276
46
  r = iso_drv->ops->pin_cmd(card, data);
6277
46
  priv->pin_cmd_verify = 0;
6278
6279
  /* tell user verify not supported on contactless without VCI */
6280
46
  if (priv->pin_cmd_verify_sw1 == 0x69 && priv->pin_cmd_verify_sw2 == 0x82 &&
6281
1
      priv->init_flags & PIV_INIT_CONTACTLESS &&
6282
0
      card->type == SC_CARD_TYPE_PIV_II_800_73_4) {
6283
0
    sc_log(card->ctx, "Token does not support pin verify over contacless reader");
6284
0
    r = SC_ERROR_NOT_SUPPORTED;
6285
0
  }
6286
6287
  /* if verify failed, release the lock */
6288
46
  if (data->cmd == SC_PIN_CMD_VERIFY && r < 0 && priv->context_specific) {
6289
11
    sc_log(card->ctx, "Clearing CONTEXT_SPECIFIC");
6290
11
    priv->context_specific = 0;
6291
11
    sc_unlock(card);
6292
11
  }
6293
6294
  /* if access to applet is know to be reset by other driver  we select_aid and try again */
6295
46
  if (priv->card_issues & CI_OTHER_AID_LOSE_STATE && priv->pin_cmd_verify_sw1 == 0x6DU) {
6296
10
    sc_log(card->ctx, "AID may be lost doing piv_find_aid and retry pin_cmd");
6297
10
    piv_find_aid(card);
6298
6299
10
    priv->pin_cmd_verify = 1; /* tell piv_check_sw its a verify to save sw1, sw2 */
6300
10
    r = iso_drv->ops->pin_cmd(card, data);
6301
10
    priv->pin_cmd_verify = 0;
6302
10
  }
6303
6304
  /* If verify worked, we are logged_in */
6305
46
  if (data->cmd == SC_PIN_CMD_VERIFY) {
6306
46
    if (r >= 0)
6307
21
      priv->logged_in = SC_PIN_STATE_LOGGED_IN;
6308
25
    else
6309
25
      priv->logged_in = SC_PIN_STATE_LOGGED_OUT;
6310
46
  }
6311
6312
  /* Some cards never return 90 00  for SC_PIN_CMD_GET_INFO even if the card state is verified */
6313
  /* PR 797 has changed the return codes from pin_cmd, and added a data->pin1.logged_in flag */
6314
6315
46
  if (data->cmd == SC_PIN_CMD_GET_INFO) {
6316
0
    if (priv->card_issues & CI_CANT_USE_GETDATA_FOR_STATE) {
6317
0
      sc_log(card->ctx, "CI_CANT_USE_GETDATA_FOR_STATE set, assume logged_in=%d", priv->logged_in);
6318
0
      data->pin1.logged_in = priv->logged_in; /* use what ever we saw last */
6319
0
    } else if (priv->card_issues & CI_VERIFY_LC0_FAIL &&
6320
0
        priv->pin_cmd_verify_sw1 == 0x63U) { /* can not use modified return codes from iso->drv->pin_cmd */
6321
      /* try another method, looking at a protected object this may require adding one of these to NEO */
6322
0
      r = piv_check_protected_objects(card);
6323
0
      if (r == SC_SUCCESS)
6324
0
        data->pin1.logged_in = SC_PIN_STATE_LOGGED_IN;
6325
0
      else if (r == SC_ERROR_PIN_CODE_INCORRECT) {
6326
0
        if (priv->card_issues & CI_CANT_USE_GETDATA_FOR_STATE) { /* we still can not determine login state */
6327
6328
0
          data->pin1.logged_in = priv->logged_in; /* may have be set from SC_PIN_CMD_VERIFY */
6329
0
        } else {
6330
0
          data->pin1.logged_in = SC_PIN_STATE_LOGGED_OUT;
6331
0
        }
6332
0
        r = SC_SUCCESS;
6333
0
      }
6334
0
    }
6335
0
    priv->logged_in = data->pin1.logged_in;
6336
0
    priv->tries_left = data->pin1.tries_left;
6337
0
  }
6338
6339
46
  sc_log(card->ctx, "piv_pin_cmd tries_left=%d, logged_in=%d", priv->tries_left, priv->logged_in);
6340
46
  LOG_FUNC_RETURN(card->ctx, r);
6341
46
}
6342
6343
static int
6344
piv_logout(sc_card_t *card)
6345
0
{
6346
0
  int r = SC_ERROR_INTERNAL;
6347
0
  piv_private_data_t *priv = PIV_DATA(card);
6348
6349
0
  LOG_FUNC_CALLED(card->ctx);
6350
6351
0
  if (priv) {
6352
    /* logout defined since 800-73-4 */
6353
0
    r = iso7816_logout(card, priv->pin_preference);
6354
0
    if (r == SC_SUCCESS) {
6355
0
      priv->logged_in = SC_PIN_STATE_LOGGED_OUT;
6356
0
    }
6357
0
  }
6358
6359
0
  LOG_FUNC_RETURN(card->ctx, r);
6360
0
}
6361
6362
/*
6363
 * Called when a sc_lock gets a reader lock and PCSC SCardBeginTransaction
6364
 * If SCardBeginTransaction may pass back that a card reset was seen since
6365
 * the last transaction  completed.
6366
 * There may have been one or more resets, by other card drivers in different
6367
 * processes, and they may have taken action already
6368
 * and changed the AID and or may have sent a  VERIFY with PIN
6369
 * So test the state of the card.
6370
 * this is very similar to what the piv_match routine does,
6371
 */
6372
6373
/* card.c also calls piv_sm_open before this if a reset was done, but
6374
 * does not say if a reset was done or not. May need to ignore the call
6375
 * the piv_sm_open in this case, but how? may need a open is active flag,
6376
 * in case it is the APDU done from open caused  triggered the case.
6377
 */
6378
static int
6379
piv_card_reader_lock_obtained(sc_card_t *card, int was_reset)
6380
6.26k
{
6381
6.26k
  int r = 0;
6382
6.26k
  u8 temp[SC_MAX_APDU_BUFFER_SIZE];
6383
6.26k
  size_t templen = sizeof(temp);
6384
6.26k
  piv_private_data_t *priv = PIV_DATA(card); /* may be null */
6385
6386
6.26k
  SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
6387
6388
  /* We have a PCSC transaction and sc_lock */
6389
6.26k
  if (priv == NULL || priv->pstate == PIV_STATE_MATCH) {
6390
5.53k
    sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
6391
5.53k
        priv ? "PIV_STATE_MATCH" : "priv==NULL");
6392
5.53k
    r = 0; /* do nothing, piv_match will take care of it */
6393
5.53k
    goto err;
6394
5.53k
  }
6395
6396
729
  priv->init_flags |= PIV_INIT_IN_READER_LOCK_OBTAINED;
6397
6398
  /* make sure our application is active */
6399
6400
  /* first see if AID is active AID by reading discovery object '7E' */
6401
  /* If not try selecting AID */
6402
6403
  /* but if card does not support DISCOVERY object we can not use it */
6404
729
  if (priv->card_issues & CI_DISCOVERY_USELESS) {
6405
685
    r = SC_ERROR_NO_CARD_SUPPORT;
6406
685
  } else {
6407
44
    r = piv_find_discovery(card);
6408
#ifdef ENABLE_PIV_SM
6409
    /*
6410
     * All 800-73-4 cards that support SM, also have a discovery object with
6411
     * the pin_policy, so can not have CI_DISCOVERY_USELESS
6412
     * Discovery object can be read with contact or contactless
6413
     * If read with SM and fails with 69 88  SC_ERROR_SM_INVALID_SESSION_KEY
6414
     * sm.c will close the SM connectrion, and set defer
6415
     */
6416
    if (was_reset == 0 && (r == SC_ERROR_SM_INVALID_SESSION_KEY || priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) {
6417
      sc_log(card->ctx, "SC_ERROR_SM_INVALID_SESSION_KEY || PIV_SM_FLAGS_DEFER_OPEN");
6418
      piv_sm_open(card);
6419
      r = piv_find_discovery(card);
6420
    }
6421
#endif /* ENABLE_PIV_SM */
6422
44
  }
6423
6424
729
  if (r < 0) {
6425
716
    if (was_reset > 0 || !(priv->card_issues & CI_PIV_AID_LOSE_STATE)) {
6426
709
      r = iso7816_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen);
6427
709
      sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "iso7816_select_aid card->type:%d r:%d\n", card->type, r);
6428
709
    } else {
6429
7
      r = 0; /* can't do anything with this card, hope there was no interference */
6430
7
    }
6431
716
  }
6432
6433
729
  if (r < 0) /* bad error return will show up in sc_lock as error*/
6434
573
    goto err;
6435
6436
156
  if (was_reset > 0)
6437
0
    priv->logged_in = SC_PIN_STATE_UNKNOWN;
6438
6439
156
  r = 0;
6440
6441
6.26k
err:
6442
6.26k
  if (priv)
6443
1.40k
    priv->init_flags &= ~PIV_INIT_IN_READER_LOCK_OBTAINED;
6444
6.26k
  LOG_FUNC_RETURN(card->ctx, r);
6445
6.26k
}
6446
6447
static struct sc_card_driver *
6448
sc_get_driver(void)
6449
14.4k
{
6450
14.4k
  struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
6451
6452
14.4k
  piv_ops = *iso_drv->ops;
6453
14.4k
  piv_ops.match_card = piv_match_card;
6454
14.4k
  piv_ops.init = piv_init;
6455
14.4k
  piv_ops.finish = piv_finish;
6456
6457
14.4k
  piv_ops.select_file = piv_select_file; /* must use get/put, could emulate? */
6458
14.4k
  piv_ops.get_challenge = piv_get_challenge;
6459
14.4k
  piv_ops.logout = piv_logout;
6460
14.4k
  piv_ops.read_binary = piv_read_binary;
6461
14.4k
  piv_ops.write_binary = piv_write_binary;
6462
14.4k
  piv_ops.set_security_env = piv_set_security_env;
6463
14.4k
  piv_ops.restore_security_env = piv_restore_security_env;
6464
14.4k
  piv_ops.compute_signature = piv_compute_signature;
6465
14.4k
  piv_ops.decipher = piv_decipher;
6466
14.4k
  piv_ops.check_sw = piv_check_sw;
6467
14.4k
  piv_ops.card_ctl = piv_card_ctl;
6468
14.4k
  piv_ops.pin_cmd = piv_pin_cmd;
6469
14.4k
  piv_ops.card_reader_lock_obtained = piv_card_reader_lock_obtained;
6470
6471
14.4k
  return &piv_drv;
6472
14.4k
}
6473
6474
struct sc_card_driver *
6475
sc_get_piv_driver(void)
6476
14.4k
{
6477
14.4k
  return sc_get_driver();
6478
14.4k
}