Coverage Report

Created: 2026-03-01 06:54

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