1 /*
2 * card-iasecc.c: Support for IAS/ECC smart cards
3 *
4 * Copyright (C) 2010 Viktor Tarasov <vtarasov@gmail.com>
5 * OpenTrust <www.opentrust.com>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #ifdef ENABLE_OPENSSL /* empty file without openssl */
27
28 #include <string.h>
29 #include <stdlib.h>
30
31 #include <openssl/bn.h>
32 #include <openssl/evp.h>
33 #include <openssl/pem.h>
34 #include <openssl/err.h>
35 #include <openssl/rand.h>
36 #include <openssl/sha.h>
37 #include <openssl/rsa.h>
38 #include <openssl/pkcs12.h>
39 #include <openssl/x509v3.h>
40
41 #include "internal.h"
42 #include "asn1.h"
43 #include "cardctl.h"
44 #include "opensc.h"
45 /* #include "sm.h" */
46 #include "pkcs15.h"
47 /* #include "hash-strings.h" */
48 #include "gp.h"
49
50 #include "iasecc.h"
51
52 #define IASECC_CARD_DEFAULT_FLAGS ( 0 \
53 | SC_ALGORITHM_ONBOARD_KEY_GEN \
54 | SC_ALGORITHM_RSA_PAD_ISO9796 \
55 | SC_ALGORITHM_RSA_PAD_PKCS1 \
56 | SC_ALGORITHM_RSA_HASH_NONE \
57 | SC_ALGORITHM_RSA_HASH_SHA1 \
58 | SC_ALGORITHM_RSA_HASH_SHA256)
59
60 #define IASECC_CARD_DEFAULT_CAPS ( 0 \
61 | SC_CARD_CAP_RNG \
62 | SC_CARD_CAP_APDU_EXT \
63 | SC_CARD_CAP_USE_FCI_AC \
64 | SC_CARD_CAP_ISO7816_PIN_INFO)
65
66 /* generic iso 7816 operations table */
67 static const struct sc_card_operations *iso_ops = NULL;
68
69 /* our operations table with overrides */
70 static struct sc_card_operations iasecc_ops;
71
72 static struct sc_card_driver iasecc_drv = {
73 "IAS-ECC",
74 "iasecc",
75 &iasecc_ops,
76 NULL, 0, NULL
77 };
78
79 static const struct sc_atr_table iasecc_known_atrs[] = {
80 { "3B:7F:96:00:00:00:31:B8:64:40:70:14:10:73:94:01:80:82:90:00",
81 "FF:FF:FF:FF:FF:FF:FF:FE:FF:FF:00:00:FF:FF:FF:FF:FF:FF:FF:FF",
82 "IAS/ECC Gemalto", SC_CARD_TYPE_IASECC_GEMALTO, 0, NULL },
83 { "3B:DD:00:00:81:31:FE:45:80:F9:A0:00:00:00:77:01:08:00:07:90:00:00",
84 "FF:FF:00:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:FF:00",
85 "IAS/ECC v1.0.1 Oberthur", SC_CARD_TYPE_IASECC_OBERTHUR, 0, NULL },
86 { "3B:7D:13:00:00:4D:44:57:2D:49:41:53:2D:43:41:52:44:32", NULL,
87 "IAS/ECC v1.0.1 Sagem MDW-IAS-CARD2", SC_CARD_TYPE_IASECC_SAGEM, 0, NULL },
88 { "3B:7F:18:00:00:00:31:B8:64:50:23:EC:C1:73:94:01:80:82:90:00", NULL,
89 "IAS/ECC v1.0.1 Sagem ypsID S3", SC_CARD_TYPE_IASECC_SAGEM, 0, NULL },
90 { "3B:DF:96:00:80:31:FE:45:00:31:B8:64:04:1F:EC:C1:73:94:01:80:82:90:00:EC", NULL,
91 "IAS/ECC Morpho MinInt - Agent Card", SC_CARD_TYPE_IASECC_MI, 0, NULL },
92 { "3B:DF:18:FF:81:91:FE:1F:C3:00:31:B8:64:0C:01:EC:C1:73:94:01:80:82:90:00:B3", NULL,
93 "IAS/ECC v1.0.1 Amos", SC_CARD_TYPE_IASECC_AMOS, 0, NULL },
94 { "3B:DC:18:FF:81:91:FE:1F:C3:80:73:C8:21:13:66:02:04:03:55:00:02:34", NULL,
95 "IAS/ECC v1.0.1 Amos", SC_CARD_TYPE_IASECC_AMOS, 0, NULL },
96 { "3B:DC:18:FF:81:91:FE:1F:C3:80:73:C8:21:13:66:01:0B:03:52:00:05:38", NULL,
97 "IAS/ECC v1.0.1 Amos", SC_CARD_TYPE_IASECC_AMOS, 0, NULL },
98 {
99 .atr = "3B:AC:00:40:2A:00:12:25:00:64:80:00:03:10:00:90:00",
100 .atrmask = "FF:00:00:00:00:FF:FF:FF:FF:FF:FF:00:00:00:FF:FF:FF",
101 .name = "IAS/ECC CPx",
102 .type = SC_CARD_TYPE_IASECC_CPX,
103 },
104 {
105 .atr = "2B:8F:80:01:00:31:B8:64:04:B0:EC:C1:73:94:01:80:82:90:00:0E",
106 .atrmask = "FF:FF:FF:FF:FF:FF:FF:FF:00:00:FF:C0:FF:FF:FF:FF:FF:FF:FF:FF",
107 .name = "IAS/ECC CPxCL",
108 .type = SC_CARD_TYPE_IASECC_CPXCL,
109 },
110 { NULL, NULL, NULL, 0, 0, NULL }
111 };
112
113 static struct sc_aid OberthurIASECC_AID = {
114 {0xA0,0x00,0x00,0x00,0x77,0x01,0x08,0x00,0x07,0x00,0x00,0xFE,0x00,0x00,0x01,0x00}, 16
115 };
116
117 static struct sc_aid MIIASECC_AID = {
118 { 0x4D, 0x49, 0x4F, 0x4D, 0x43, 0x54}, 6
119 };
120
121 struct iasecc_pin_status {
122 unsigned char sha1[SHA_DIGEST_LENGTH];
123 unsigned char reference;
124
125 struct iasecc_pin_status *next;
126 struct iasecc_pin_status *prev;
127 };
128
129 struct iasecc_pin_status *checked_pins = NULL;
130
131 /* Any absent field is set to -1, except scbs, which is always present */
132 struct iasecc_pin_policy {
133 int min_length;
134 int max_length;
135 int stored_length;
136 int tries_maximum;
137 int tries_remaining;
138 unsigned char scbs[IASECC_MAX_SCBS];
139 };
140
141 static int iasecc_select_file(struct sc_card *card, const struct sc_path *path, struct sc_file **file_out);
142 static int iasecc_process_fci(struct sc_card *card, struct sc_file *file, const unsigned char *buf, size_t buflen);
143 static int iasecc_get_serialnr(struct sc_card *card, struct sc_serial_number *serial);
144 static int iasecc_sdo_get_data(struct sc_card *card, struct iasecc_sdo *sdo);
145 static int iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struct iasecc_pin_policy *pin);
146 static int iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left);
147 static int iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left);
148 static int iasecc_check_update_pin(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin);
149 static void iasecc_set_pin_padding(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin,
150 size_t pad_len);
151 static int iasecc_pin_merge_policy(struct sc_card *card, struct sc_pin_cmd_data *data,
152 struct sc_pin_cmd_pin *pin, struct iasecc_pin_policy *policy);
153 static int iasecc_get_free_reference(struct sc_card *card, struct iasecc_ctl_get_free_reference *ctl_data);
154 static int iasecc_sdo_put_data(struct sc_card *card, struct iasecc_sdo_update *update);
155
156 #ifdef ENABLE_SM
157 static int _iasecc_sm_read_binary(struct sc_card *card, unsigned int offs, unsigned char *buf, size_t count);
158 static int _iasecc_sm_update_binary(struct sc_card *card, unsigned int offs, const unsigned char *buff, size_t count);
159 #endif
160
161 static int
iasecc_chv_cache_verified(struct sc_card * card,struct sc_pin_cmd_data * pin_cmd)162 iasecc_chv_cache_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd)
163 {
164 struct sc_context *ctx = card->ctx;
165 struct iasecc_pin_status *pin_status = NULL, *current = NULL;
166
167 LOG_FUNC_CALLED(ctx);
168
169 for(current = checked_pins; current; current = current->next)
170 if (current->reference == pin_cmd->pin_reference)
171 break;
172
173 if (current) {
174 sc_log(ctx, "iasecc_chv_cache_verified() current PIN-%i", current->reference);
175 pin_status = current;
176 }
177 else {
178 pin_status = calloc(1, sizeof(struct iasecc_pin_status));
179 if (!pin_status)
180 LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot callocate PIN status info");
181 sc_log(ctx, "iasecc_chv_cache_verified() allocated %p", pin_status);
182 }
183
184 pin_status->reference = pin_cmd->pin_reference;
185 if (pin_cmd->pin1.data)
186 SHA1(pin_cmd->pin1.data, pin_cmd->pin1.len, pin_status->sha1);
187 else
188 memset(pin_status->sha1, 0, SHA_DIGEST_LENGTH);
189
190 sc_log_hex(ctx, "iasecc_chv_cache_verified() sha1(PIN)", pin_status->sha1, SHA_DIGEST_LENGTH);
191
192 if (!current) {
193 if (!checked_pins) {
194 checked_pins = pin_status;
195 }
196 else {
197 checked_pins->prev = pin_status;
198 pin_status->next = checked_pins;
199 checked_pins = pin_status;
200 }
201 }
202
203 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
204 }
205
206
207 static int
iasecc_chv_cache_clean(struct sc_card * card,struct sc_pin_cmd_data * pin_cmd)208 iasecc_chv_cache_clean(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd)
209 {
210 struct sc_context *ctx = card->ctx;
211 struct iasecc_pin_status *current = NULL;
212
213 LOG_FUNC_CALLED(ctx);
214
215 for(current = checked_pins; current; current = current->next)
216 if (current->reference == pin_cmd->pin_reference)
217 break;
218
219 if (!current)
220 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
221
222
223 if (current->next && current->prev) {
224 current->prev->next = current->next;
225 current->next->prev = current->prev;
226 }
227 else if (!current->prev) {
228 checked_pins = current->next;
229 }
230 else if (!current->next && current->prev) {
231 current->prev->next = NULL;
232 }
233
234 free(current);
235 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
236 }
237
238
239 static struct iasecc_pin_status *
iasecc_chv_cache_is_verified(struct sc_card * card,struct sc_pin_cmd_data * pin_cmd)240 iasecc_chv_cache_is_verified(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd)
241 {
242 struct sc_context *ctx = card->ctx;
243 struct iasecc_pin_status *current = NULL;
244 unsigned char data_sha1[SHA_DIGEST_LENGTH];
245
246 LOG_FUNC_CALLED(ctx);
247
248 if (pin_cmd->pin1.data)
249 SHA1(pin_cmd->pin1.data, pin_cmd->pin1.len, data_sha1);
250 else
251 memset(data_sha1, 0, SHA_DIGEST_LENGTH);
252 sc_log_hex(ctx, "data_sha1: %s", data_sha1, SHA_DIGEST_LENGTH);
253
254 for(current = checked_pins; current; current = current->next)
255 if (current->reference == pin_cmd->pin_reference)
256 break;
257
258 if (current && !memcmp(data_sha1, current->sha1, SHA_DIGEST_LENGTH)) {
259 sc_log(ctx, "PIN-%i status 'verified'", pin_cmd->pin_reference);
260 return current;
261 }
262
263 sc_log(ctx, "PIN-%i status 'not verified'", pin_cmd->pin_reference);
264 return NULL;
265 }
266
267
268 static int
iasecc_select_mf(struct sc_card * card,struct sc_file ** file_out)269 iasecc_select_mf(struct sc_card *card, struct sc_file **file_out)
270 {
271 struct sc_context *ctx = card->ctx;
272 struct sc_file *mf_file = NULL;
273 struct sc_path path;
274 int rv;
275
276 LOG_FUNC_CALLED(ctx);
277
278 if (file_out)
279 *file_out = NULL;
280
281 memset(&path, 0, sizeof(struct sc_path));
282 if (!card->ef_atr || !card->ef_atr->aid.len) {
283 struct sc_apdu apdu;
284 unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE];
285
286 /* ISO 'select' command fails when not FCP data returned */
287 sc_format_path("3F00", &path);
288 path.type = SC_PATH_TYPE_FILE_ID;
289
290 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x00, 0x0C);
291 apdu.lc = path.len;
292 apdu.data = path.value;
293 apdu.datalen = path.len;
294 apdu.resplen = sizeof(apdu_resp);
295 apdu.resp = apdu_resp;
296
297 /* TODO: this might be obsolete now that 0x0c (no data) is default for p2 */
298 if (card->type == SC_CARD_TYPE_IASECC_MI2)
299 apdu.p2 = 0x04;
300
301 rv = sc_transmit_apdu(card, &apdu);
302 LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
303 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
304 LOG_TEST_RET(card->ctx, rv, "Cannot select MF");
305 }
306 else {
307 memset(&path, 0, sizeof(path));
308 path.type = SC_PATH_TYPE_DF_NAME;
309 memcpy(path.value, card->ef_atr->aid.value, card->ef_atr->aid.len);
310 path.len = card->ef_atr->aid.len;
311 rv = iasecc_select_file(card, &path, file_out);
312 LOG_TEST_RET(ctx, rv, "Unable to ROOT selection");
313 }
314
315 /* Ignore the FCP of the MF, because:
316 * - some cards do not return it;
317 * - there is not need of it -- create/delete of the files in MF is not envisaged.
318 */
319 mf_file = sc_file_new();
320 if (mf_file == NULL)
321 LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate MF file");
322 mf_file->type = SC_FILE_TYPE_DF;
323 mf_file->path = path;
324
325 if (card->cache.valid) {
326 sc_file_free(card->cache.current_df);
327 }
328 card->cache.current_df = NULL;
329
330 if (card->cache.valid) {
331 sc_file_free(card->cache.current_ef);
332 }
333 card->cache.current_ef = NULL;
334
335 sc_file_dup(&card->cache.current_df, mf_file);
336 card->cache.valid = 1;
337
338 if (file_out && *file_out == NULL)
339 *file_out = mf_file;
340 else
341 sc_file_free(mf_file);
342
343 LOG_FUNC_RETURN(ctx, rv);
344 }
345
346
347 static int
iasecc_select_aid(struct sc_card * card,struct sc_aid * aid,unsigned char * out,size_t * out_len)348 iasecc_select_aid(struct sc_card *card, struct sc_aid *aid, unsigned char *out, size_t *out_len)
349 {
350 struct sc_apdu apdu;
351 unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE];
352 int rv;
353
354 LOG_FUNC_CALLED(card->ctx);
355
356 /* Select application (deselect previously selected application) */
357 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x04, 0x00);
358 apdu.lc = aid->len;
359 apdu.data = aid->value;
360 apdu.datalen = aid->len;
361 apdu.resplen = sizeof(apdu_resp);
362 apdu.resp = apdu_resp;
363
364 rv = sc_transmit_apdu(card, &apdu);
365 LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
366 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
367 LOG_TEST_RET(card->ctx, rv, "Cannot select AID");
368
369 if (*out_len < apdu.resplen)
370 LOG_TEST_RET(card->ctx, SC_ERROR_BUFFER_TOO_SMALL, "Cannot select AID");
371 memcpy(out, apdu.resp, apdu.resplen);
372
373 LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
374 }
375
376
377 static int
iasecc_match_card(struct sc_card * card)378 iasecc_match_card(struct sc_card *card)
379 {
380 struct sc_context *ctx = card->ctx;
381 int i;
382
383 i = _sc_match_atr(card, iasecc_known_atrs, &card->type);
384 if (i < 0) {
385 sc_log(ctx, "card not matched");
386 return 0;
387 }
388
389 sc_log(ctx, "'%s' card matched", iasecc_known_atrs[i].name);
390 return 1;
391 }
392
393
iasecc_parse_ef_atr(struct sc_card * card)394 static int iasecc_parse_ef_atr(struct sc_card *card)
395 {
396 struct sc_context *ctx = card->ctx;
397 struct iasecc_private_data *pdata = (struct iasecc_private_data *) card->drv_data;
398 struct iasecc_version *version = &pdata->version;
399 struct iasecc_io_buffer_sizes *sizes = &pdata->max_sizes;
400 int rv;
401
402 LOG_FUNC_CALLED(ctx);
403 rv = sc_parse_ef_atr(card);
404 LOG_TEST_RET(ctx, rv, "MF selection error");
405
406 if (card->ef_atr->pre_issuing_len < 4)
407 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid pre-issuing data");
408
409 version->ic_manufacturer = card->ef_atr->pre_issuing[0];
410 version->ic_type = card->ef_atr->pre_issuing[1];
411 version->os_version = card->ef_atr->pre_issuing[2];
412 version->iasecc_version = card->ef_atr->pre_issuing[3];
413 sc_log(ctx, "EF.ATR: IC manufacturer/type %X/%X, OS/IasEcc versions %X/%X",
414 version->ic_manufacturer, version->ic_type, version->os_version, version->iasecc_version);
415
416 if (card->ef_atr->issuer_data_len < 16)
417 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid issuer data");
418
419 sizes->send = card->ef_atr->issuer_data[2] * 0x100 + card->ef_atr->issuer_data[3];
420 sizes->send_sc = card->ef_atr->issuer_data[6] * 0x100 + card->ef_atr->issuer_data[7];
421 sizes->recv = card->ef_atr->issuer_data[10] * 0x100 + card->ef_atr->issuer_data[11];
422 sizes->recv_sc = card->ef_atr->issuer_data[14] * 0x100 + card->ef_atr->issuer_data[15];
423
424 sc_log(ctx,
425 "EF.ATR: IO Buffer Size send/sc %"SC_FORMAT_LEN_SIZE_T"d/%"SC_FORMAT_LEN_SIZE_T"d "
426 "recv/sc %"SC_FORMAT_LEN_SIZE_T"d/%"SC_FORMAT_LEN_SIZE_T"d",
427 sizes->send, sizes->send_sc, sizes->recv, sizes->recv_sc);
428
429 card->max_send_size = sizes->send;
430 card->max_recv_size = sizes->recv;
431
432 /* Most of the card producers interpret 'send' values as "maximum APDU data size".
433 * Oberthur strictly follows specification and interpret these values as "maximum APDU command size".
434 * Here we need 'data size'.
435 */
436 if (card->max_send_size > 0xFF)
437 card->max_send_size -= 5;
438
439 sc_log(ctx,
440 "EF.ATR: max send/recv sizes %"SC_FORMAT_LEN_SIZE_T"X/%"SC_FORMAT_LEN_SIZE_T"X",
441 card->max_send_size, card->max_recv_size);
442
443 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
444 }
445
446
447 static int
iasecc_init_gemalto(struct sc_card * card)448 iasecc_init_gemalto(struct sc_card *card)
449 {
450 struct sc_context *ctx = card->ctx;
451 struct sc_path path;
452 unsigned int flags;
453 int rv = 0;
454
455 LOG_FUNC_CALLED(ctx);
456
457 flags = IASECC_CARD_DEFAULT_FLAGS;
458
459 card->caps = IASECC_CARD_DEFAULT_CAPS;
460
461 sc_format_path("3F00", &path);
462 if (SC_SUCCESS != sc_select_file(card, &path, NULL)) {
463 /* Result ignored*/
464 sc_log(card->ctx, "Warning, MF select failed");
465 }
466
467 rv = iasecc_parse_ef_atr(card);
468 sc_log(ctx, "rv %i", rv);
469 if (rv == SC_ERROR_FILE_NOT_FOUND) {
470 sc_log(ctx, "Select MF");
471 rv = iasecc_select_mf(card, NULL);
472 sc_log(ctx, "rv %i", rv);
473 LOG_TEST_RET(ctx, rv, "MF selection error");
474
475 rv = iasecc_parse_ef_atr(card);
476 sc_log(ctx, "rv %i", rv);
477 }
478 sc_log(ctx, "rv %i", rv);
479 LOG_TEST_RET(ctx, rv, "Cannot read/parse EF.ATR");
480
481 _sc_card_add_rsa_alg(card, 1024, flags, 0x10001);
482 _sc_card_add_rsa_alg(card, 2048, flags, 0x10001);
483
484 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
485 }
486
487
488 static int
iasecc_oberthur_match(struct sc_card * card)489 iasecc_oberthur_match(struct sc_card *card)
490 {
491 struct sc_context *ctx = card->ctx;
492 unsigned char *hist = card->reader->atr_info.hist_bytes;
493
494 LOG_FUNC_CALLED(ctx);
495
496 if (*hist != 0x80 || ((*(hist+1)&0xF0) != 0xF0))
497 LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND);
498
499 sc_log_hex(ctx, "AID in historical_bytes", hist + 2, *(hist+1) & 0x0F);
500
501 if (memcmp(hist + 2, OberthurIASECC_AID.value, *(hist+1) & 0x0F))
502 LOG_FUNC_RETURN(ctx, SC_ERROR_RECORD_NOT_FOUND);
503
504 if (!card->ef_atr)
505 card->ef_atr = calloc(1, sizeof(struct sc_ef_atr));
506 if (!card->ef_atr)
507 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
508
509 memcpy(card->ef_atr->aid.value, OberthurIASECC_AID.value, OberthurIASECC_AID.len);
510 card->ef_atr->aid.len = OberthurIASECC_AID.len;
511
512 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
513 }
514
515
516 static int
iasecc_init_oberthur(struct sc_card * card)517 iasecc_init_oberthur(struct sc_card *card)
518 {
519 struct sc_context *ctx = card->ctx;
520 unsigned int flags;
521 int rv = 0;
522
523 LOG_FUNC_CALLED(ctx);
524
525 flags = IASECC_CARD_DEFAULT_FLAGS;
526
527 _sc_card_add_rsa_alg(card, 1024, flags, 0x10001);
528 _sc_card_add_rsa_alg(card, 2048, flags, 0x10001);
529
530 card->caps = IASECC_CARD_DEFAULT_CAPS;
531
532 iasecc_parse_ef_atr(card);
533
534 /* if we fail to select CM, */
535 if (gp_select_card_manager(card)) {
536 gp_select_isd_rid(card);
537 }
538
539 rv = iasecc_oberthur_match(card);
540 LOG_TEST_RET(ctx, rv, "unknown Oberthur's IAS/ECC card");
541
542 rv = iasecc_select_mf(card, NULL);
543 LOG_TEST_RET(ctx, rv, "MF selection error");
544
545 rv = iasecc_parse_ef_atr(card);
546 LOG_TEST_RET(ctx, rv, "EF.ATR read or parse error");
547
548 sc_log(ctx, "EF.ATR(aid:'%s')", sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len));
549 LOG_FUNC_RETURN(ctx, rv);
550 }
551
552
553 static int
iasecc_mi_match(struct sc_card * card)554 iasecc_mi_match(struct sc_card *card)
555 {
556 struct sc_context *ctx = card->ctx;
557 unsigned char resp[0x100];
558 size_t resp_len;
559 int rv = 0;
560
561 LOG_FUNC_CALLED(ctx);
562
563 resp_len = sizeof(resp);
564 rv = iasecc_select_aid(card, &MIIASECC_AID, resp, &resp_len);
565 LOG_TEST_RET(ctx, rv, "IASECC: failed to select MI IAS/ECC applet");
566
567 if (!card->ef_atr)
568 card->ef_atr = calloc(1, sizeof(struct sc_ef_atr));
569 if (!card->ef_atr)
570 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
571
572 memcpy(card->ef_atr->aid.value, MIIASECC_AID.value, MIIASECC_AID.len);
573 card->ef_atr->aid.len = MIIASECC_AID.len;
574
575 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
576 }
577
578
579 static int
iasecc_init_amos_or_sagem(struct sc_card * card)580 iasecc_init_amos_or_sagem(struct sc_card *card)
581 {
582 struct sc_context *ctx = card->ctx;
583 unsigned int flags;
584 int rv = 0;
585
586 LOG_FUNC_CALLED(ctx);
587
588 flags = IASECC_CARD_DEFAULT_FLAGS;
589
590 _sc_card_add_rsa_alg(card, 1024, flags, 0x10001);
591 _sc_card_add_rsa_alg(card, 2048, flags, 0x10001);
592
593 card->caps = IASECC_CARD_DEFAULT_CAPS;
594
595 if (card->type == SC_CARD_TYPE_IASECC_MI) {
596 rv = iasecc_mi_match(card);
597 if (rv)
598 card->type = SC_CARD_TYPE_IASECC_MI2;
599 else
600 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
601 }
602
603 rv = iasecc_parse_ef_atr(card);
604 if (rv == SC_ERROR_FILE_NOT_FOUND) {
605 rv = iasecc_select_mf(card, NULL);
606 LOG_TEST_RET(ctx, rv, "MF selection error");
607
608 rv = iasecc_parse_ef_atr(card);
609 }
610 LOG_TEST_RET(ctx, rv, "IASECC: ATR parse failed");
611
612 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
613 }
614
615 inline static int
iasecc_is_cpx(const struct sc_card * card)616 iasecc_is_cpx(const struct sc_card *card)
617 {
618 switch(card->type) {
619 case SC_CARD_TYPE_IASECC_CPX:
620 case SC_CARD_TYPE_IASECC_CPXCL:
621 return 1;
622 default:
623 return 0;
624 }
625
626 return 0;
627 }
628
629 static int
iasecc_init_cpx(struct sc_card * card)630 iasecc_init_cpx(struct sc_card *card)
631 {
632 struct sc_context *ctx = card->ctx;
633 unsigned int flags;
634 int rv = 0;
635
636 LOG_FUNC_CALLED(ctx);
637
638 card->caps = IASECC_CARD_DEFAULT_CAPS;
639
640 flags = IASECC_CARD_DEFAULT_FLAGS;
641
642 _sc_card_add_rsa_alg(card, 512, flags, 0);
643 _sc_card_add_rsa_alg(card, 1024, flags, 0);
644 _sc_card_add_rsa_alg(card, 2048, flags, 0);
645
646 rv = iasecc_parse_ef_atr(card);
647 if (rv)
648 sc_invalidate_cache(card); /* avoid memory leakage */
649 LOG_TEST_RET(ctx, rv, "Parse EF.ATR");
650
651 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
652 }
653
654
655 static int
iasecc_init(struct sc_card * card)656 iasecc_init(struct sc_card *card)
657 {
658 struct sc_context *ctx = card->ctx;
659 struct iasecc_private_data *private_data = NULL;
660 int rv = SC_ERROR_NO_CARD_SUPPORT;
661 void *old_drv_data = card->drv_data;
662
663 LOG_FUNC_CALLED(ctx);
664 private_data = (struct iasecc_private_data *) calloc(1, sizeof(struct iasecc_private_data));
665 if (private_data == NULL)
666 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
667
668 card->cla = 0x00;
669 card->drv_data = private_data;
670
671 if (card->type == SC_CARD_TYPE_IASECC_GEMALTO)
672 rv = iasecc_init_gemalto(card);
673 else if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR)
674 rv = iasecc_init_oberthur(card);
675 else if (card->type == SC_CARD_TYPE_IASECC_SAGEM)
676 rv = iasecc_init_amos_or_sagem(card);
677 else if (card->type == SC_CARD_TYPE_IASECC_AMOS)
678 rv = iasecc_init_amos_or_sagem(card);
679 else if (card->type == SC_CARD_TYPE_IASECC_MI)
680 rv = iasecc_init_amos_or_sagem(card);
681 else if (iasecc_is_cpx(card))
682 rv = iasecc_init_cpx(card);
683 else {
684 LOG_TEST_GOTO_ERR(ctx, SC_ERROR_INVALID_CARD, "");
685 }
686
687
688 if (!rv) {
689 if (card->ef_atr && card->ef_atr->aid.len) {
690 struct sc_path path;
691
692 memset(&path, 0, sizeof(struct sc_path));
693 path.type = SC_PATH_TYPE_DF_NAME;
694 memcpy(path.value, card->ef_atr->aid.value, card->ef_atr->aid.len);
695 path.len = card->ef_atr->aid.len;
696
697 rv = iasecc_select_file(card, &path, NULL);
698 sc_log(ctx, "Select ECC ROOT with the AID from EF.ATR: rv %i", rv);
699 LOG_TEST_GOTO_ERR(ctx, rv, "Select EF.ATR AID failed");
700 }
701
702 iasecc_get_serialnr(card, NULL);
703 }
704
705 #ifdef ENABLE_SM
706 card->sm_ctx.ops.read_binary = _iasecc_sm_read_binary;
707 card->sm_ctx.ops.update_binary = _iasecc_sm_update_binary;
708 #endif
709
710 if (!rv && card->ef_atr && card->ef_atr->aid.len) {
711 sc_log(ctx, "EF.ATR(aid:'%s')", sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len));
712 }
713
714 err:
715 if (rv < 0) {
716 free(private_data);
717 card->drv_data = old_drv_data;
718 } else {
719 free(old_drv_data);
720 }
721
722 LOG_FUNC_RETURN(ctx, rv);
723 }
724
725
726 static int
iasecc_read_binary(struct sc_card * card,unsigned int offs,unsigned char * buf,size_t count,unsigned long flags)727 iasecc_read_binary(struct sc_card *card, unsigned int offs,
728 unsigned char *buf, size_t count, unsigned long flags)
729 {
730 struct sc_context *ctx = card->ctx;
731 struct sc_apdu apdu;
732 int rv;
733
734 LOG_FUNC_CALLED(ctx);
735 sc_log(ctx,
736 "iasecc_read_binary(card:%p) offs %i; count %"SC_FORMAT_LEN_SIZE_T"u",
737 card, offs, count);
738 if (offs > 0x7fff) {
739 sc_log(ctx, "invalid EF offset: 0x%X > 0x7FFF", offs);
740 return SC_ERROR_OFFSET_TOO_LARGE;
741 }
742
743 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, (offs >> 8) & 0x7F, offs & 0xFF);
744 apdu.le = count < 0x100 ? count : 0x100;
745 apdu.resplen = count;
746 apdu.resp = buf;
747
748 rv = sc_transmit_apdu(card, &apdu);
749 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
750 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
751 LOG_TEST_RET(ctx, rv, "iasecc_read_binary() failed");
752 sc_log(ctx,
753 "iasecc_read_binary() apdu.resplen %"SC_FORMAT_LEN_SIZE_T"u",
754 apdu.resplen);
755
756 if (apdu.resplen == IASECC_READ_BINARY_LENGTH_MAX && apdu.resplen < count) {
757 rv = iasecc_read_binary(card, offs + apdu.resplen, buf + apdu.resplen, count - apdu.resplen, flags);
758 if (rv != SC_ERROR_WRONG_LENGTH) {
759 LOG_TEST_RET(ctx, rv, "iasecc_read_binary() read tail failed");
760 apdu.resplen += rv;
761 }
762 }
763
764 LOG_FUNC_RETURN(ctx, apdu.resplen);
765 }
766
767
768 static int
iasecc_erase_binary(struct sc_card * card,unsigned int offs,size_t count,unsigned long flags)769 iasecc_erase_binary(struct sc_card *card, unsigned int offs, size_t count, unsigned long flags)
770 {
771 struct sc_context *ctx = card->ctx;
772 unsigned char *tmp = NULL;
773 int rv;
774
775 LOG_FUNC_CALLED(ctx);
776 sc_log(ctx,
777 "iasecc_erase_binary(card:%p) count %"SC_FORMAT_LEN_SIZE_T"u",
778 card, count);
779 if (!count)
780 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "'ERASE BINARY' failed: invalid size to erase");
781
782 tmp = malloc(count);
783 if (!tmp)
784 LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate temporary buffer");
785 memset(tmp, 0xFF, count);
786
787 rv = sc_update_binary(card, offs, tmp, count, flags);
788 free(tmp);
789
790 LOG_FUNC_RETURN(ctx, rv);
791 }
792
793
794 #if ENABLE_SM
795 static int
_iasecc_sm_read_binary(struct sc_card * card,unsigned int offs,unsigned char * buff,size_t count)796 _iasecc_sm_read_binary(struct sc_card *card, unsigned int offs,
797 unsigned char *buff, size_t count)
798 {
799 struct sc_context *ctx = card->ctx;
800 const struct sc_acl_entry *entry = NULL;
801 int rv;
802
803 LOG_FUNC_CALLED(ctx);
804 sc_log(ctx,
805 "iasecc_sm_read_binary() card:%p offs:%i count:%"SC_FORMAT_LEN_SIZE_T"u ",
806 card, offs, count);
807 if (offs > 0x7fff)
808 LOG_TEST_RET(ctx, SC_ERROR_OFFSET_TOO_LARGE, "Invalid arguments");
809
810 if (count == 0)
811 return 0;
812
813 sc_print_cache(card);
814
815 if (card->cache.valid && card->cache.current_ef) {
816 entry = sc_file_get_acl_entry(card->cache.current_ef, SC_AC_OP_READ);
817 if (!entry)
818 LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_sm_read() 'READ' ACL not present");
819
820 sc_log(ctx, "READ method/reference %X/%X", entry->method, entry->key_ref);
821 if ((entry->method == SC_AC_SCB) && (entry->key_ref & IASECC_SCB_METHOD_SM)) {
822 unsigned char se_num = (entry->method == SC_AC_SCB) ? (entry->key_ref & IASECC_SCB_METHOD_MASK_REF) : 0;
823
824 rv = iasecc_sm_read_binary(card, se_num, offs, buff, count);
825 LOG_FUNC_RETURN(ctx, rv);
826 }
827 }
828
829 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
830 }
831
832
833 static int
_iasecc_sm_update_binary(struct sc_card * card,unsigned int offs,const unsigned char * buff,size_t count)834 _iasecc_sm_update_binary(struct sc_card *card, unsigned int offs,
835 const unsigned char *buff, size_t count)
836 {
837 struct sc_context *ctx = card->ctx;
838 const struct sc_acl_entry *entry = NULL;
839 int rv;
840
841 if (count == 0)
842 return SC_SUCCESS;
843
844 LOG_FUNC_CALLED(ctx);
845 sc_log(ctx,
846 "iasecc_sm_read_binary() card:%p offs:%i count:%"SC_FORMAT_LEN_SIZE_T"u ",
847 card, offs, count);
848 sc_print_cache(card);
849
850 if (card->cache.valid && card->cache.current_ef) {
851 entry = sc_file_get_acl_entry(card->cache.current_ef, SC_AC_OP_UPDATE);
852 if (!entry)
853 LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_sm_update() 'UPDATE' ACL not present");
854
855 sc_log(ctx, "UPDATE method/reference %X/%X", entry->method, entry->key_ref);
856 if (entry->method == SC_AC_SCB && (entry->key_ref & IASECC_SCB_METHOD_SM)) {
857 unsigned char se_num = entry->method == SC_AC_SCB ? entry->key_ref & IASECC_SCB_METHOD_MASK_REF : 0;
858
859 rv = iasecc_sm_update_binary(card, se_num, offs, buff, count);
860 LOG_FUNC_RETURN(ctx, rv);
861 }
862 }
863
864 LOG_FUNC_RETURN(ctx, 0);
865 }
866 #endif
867
868
869 static int
iasecc_emulate_fcp(struct sc_context * ctx,struct sc_apdu * apdu)870 iasecc_emulate_fcp(struct sc_context *ctx, struct sc_apdu *apdu)
871 {
872 unsigned char dummy_df_fcp[] = {
873 0x62,0xFF,
874 0x82,0x01,0x38,
875 0x8A,0x01,0x05,
876 0xA1,0x04,0x8C,0x02,0x02,0x00,
877 0x84,0xFF,
878 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
879 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF
880 };
881
882 LOG_FUNC_CALLED(ctx);
883
884 if (apdu->p1 != 0x04)
885 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "FCP emulation supported only for the DF-NAME selection type");
886 if (apdu->datalen > 16)
887 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid DF-NAME length");
888 if (apdu->resplen < apdu->datalen + 16)
889 LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "not enough space for FCP data");
890
891 memcpy(dummy_df_fcp + 16, apdu->data, apdu->datalen);
892 dummy_df_fcp[15] = apdu->datalen;
893 dummy_df_fcp[1] = apdu->datalen + 14;
894 memcpy(apdu->resp, dummy_df_fcp, apdu->datalen + 16);
895
896 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
897 }
898
899
900 /* TODO: redesign using of cache
901 * TODO: do not keep intermediate results in 'file_out' argument */
902 static int
iasecc_select_file(struct sc_card * card,const struct sc_path * path,struct sc_file ** file_out)903 iasecc_select_file(struct sc_card *card, const struct sc_path *path,
904 struct sc_file **file_out)
905 {
906 struct sc_context *ctx = card->ctx;
907 struct sc_path lpath;
908 int cache_valid = card->cache.valid, df_from_cache = 0;
909 int rv, ii;
910
911 LOG_FUNC_CALLED(ctx);
912 memcpy(&lpath, path, sizeof(struct sc_path));
913 if (file_out)
914 *file_out = NULL;
915
916 sc_log(ctx,
917 "iasecc_select_file(card:%p) path.len %"SC_FORMAT_LEN_SIZE_T"u; path.type %i; aid_len %"SC_FORMAT_LEN_SIZE_T"u",
918 card, path->len, path->type, path->aid.len);
919 sc_log(ctx, "iasecc_select_file() path:%s", sc_print_path(path));
920
921 sc_print_cache(card);
922 if ((!iasecc_is_cpx(card)) &&
923 (card->type != SC_CARD_TYPE_IASECC_GEMALTO) &&
924 (path->type != SC_PATH_TYPE_DF_NAME
925 && lpath.len >= 2
926 && lpath.value[0] == 0x3F && lpath.value[1] == 0x00)) {
927 sc_log(ctx, "EF.ATR(aid:'%s')", card->ef_atr ? sc_dump_hex(card->ef_atr->aid.value, card->ef_atr->aid.len) : "");
928
929 rv = iasecc_select_mf(card, file_out);
930 LOG_TEST_RET(ctx, rv, "MF selection error");
931
932 memmove(&lpath.value[0], &lpath.value[2], lpath.len - 2);
933 lpath.len -= 2;
934 }
935
936 if (lpath.aid.len) {
937 struct sc_file *file = NULL;
938 struct sc_path ppath;
939
940 sc_log(ctx,
941 "iasecc_select_file() select parent AID:%p/%"SC_FORMAT_LEN_SIZE_T"u",
942 lpath.aid.value, lpath.aid.len);
943 sc_log(ctx, "iasecc_select_file() select parent AID:%s", sc_dump_hex(lpath.aid.value, lpath.aid.len));
944 memset(&ppath, 0, sizeof(ppath));
945 memcpy(ppath.value, lpath.aid.value, lpath.aid.len);
946 ppath.len = lpath.aid.len;
947 ppath.type = SC_PATH_TYPE_DF_NAME;
948
949 if (card->cache.valid && card->cache.current_df
950 && card->cache.current_df->path.len == lpath.aid.len
951 && !memcmp(card->cache.current_df->path.value, lpath.aid.value, lpath.aid.len))
952 df_from_cache = 1;
953
954 rv = iasecc_select_file(card, &ppath, &file);
955 LOG_TEST_GOTO_ERR(ctx, rv, "select AID path failed");
956
957 if (file_out) {
958 sc_file_free(*file_out);
959 *file_out = file;
960 } else {
961 sc_file_free(file);
962 }
963
964 if (lpath.type == SC_PATH_TYPE_DF_NAME)
965 lpath.type = SC_PATH_TYPE_FROM_CURRENT;
966 }
967
968 if (lpath.type == SC_PATH_TYPE_PATH)
969 lpath.type = SC_PATH_TYPE_FROM_CURRENT;
970
971 if (!lpath.len) {
972 if (file_out) {
973 sc_file_free(*file_out);
974 *file_out = NULL;
975 }
976 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
977 }
978
979 sc_print_cache(card);
980
981 if (card->cache.valid && card->cache.current_df && lpath.type == SC_PATH_TYPE_DF_NAME
982 && card->cache.current_df->path.len == lpath.len
983 && !memcmp(card->cache.current_df->path.value, lpath.value, lpath.len)) {
984 sc_log(ctx, "returns current DF path %s", sc_print_path(&card->cache.current_df->path));
985 if (file_out) {
986 sc_file_free(*file_out);
987 sc_file_dup(file_out, card->cache.current_df);
988 }
989
990 sc_print_cache(card);
991 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
992 }
993
994 do {
995 struct sc_apdu apdu;
996 struct sc_file *file = NULL;
997 unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
998 int pathlen = lpath.len;
999
1000 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0x00, 0x00);
1001
1002 if (card->type != SC_CARD_TYPE_IASECC_GEMALTO
1003 && card->type != SC_CARD_TYPE_IASECC_OBERTHUR
1004 && card->type != SC_CARD_TYPE_IASECC_SAGEM
1005 && card->type != SC_CARD_TYPE_IASECC_AMOS
1006 && card->type != SC_CARD_TYPE_IASECC_MI
1007 && card->type != SC_CARD_TYPE_IASECC_MI2
1008 && !iasecc_is_cpx(card)) {
1009 rv = SC_ERROR_NOT_SUPPORTED;
1010 LOG_TEST_GOTO_ERR(ctx, rv, "Unsupported card");
1011 }
1012
1013 if (lpath.type == SC_PATH_TYPE_FILE_ID) {
1014 apdu.p1 = 0x02;
1015 if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR)
1016 apdu.p1 = 0x01;
1017 if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
1018 card->type == SC_CARD_TYPE_IASECC_AMOS ||
1019 card->type == SC_CARD_TYPE_IASECC_MI ||
1020 card->type == SC_CARD_TYPE_IASECC_MI2 ||
1021 card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
1022 iasecc_is_cpx(card)
1023 ) {
1024 apdu.p2 = 0x04;
1025 }
1026 }
1027 else if (lpath.type == SC_PATH_TYPE_FROM_CURRENT) {
1028 apdu.p1 = 0x09;
1029 if (card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
1030 card->type == SC_CARD_TYPE_IASECC_AMOS ||
1031 card->type == SC_CARD_TYPE_IASECC_MI ||
1032 card->type == SC_CARD_TYPE_IASECC_MI2 ||
1033 card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
1034 iasecc_is_cpx(card)) {
1035 apdu.p2 = 0x04;
1036 }
1037 }
1038 else if (lpath.type == SC_PATH_TYPE_PARENT) {
1039 apdu.p1 = 0x03;
1040 pathlen = 0;
1041 apdu.cse = SC_APDU_CASE_2_SHORT;
1042 }
1043 else if (lpath.type == SC_PATH_TYPE_DF_NAME) {
1044 apdu.p1 = 0x04;
1045 if (card->type == SC_CARD_TYPE_IASECC_AMOS ||
1046 card->type == SC_CARD_TYPE_IASECC_MI2 ||
1047 card->type == SC_CARD_TYPE_IASECC_OBERTHUR ||
1048 card->type == SC_CARD_TYPE_IASECC_GEMALTO ||
1049 iasecc_is_cpx(card)) {
1050 apdu.p2 = 0x04;
1051 }
1052 }
1053 else {
1054 sc_log(ctx, "Invalid PATH type: 0x%X", lpath.type);
1055 rv = SC_ERROR_NOT_SUPPORTED;
1056 LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_select_file() invalid PATH type");
1057 }
1058
1059 for (ii=0; ii<2; ii++) {
1060 apdu.lc = pathlen;
1061 apdu.data = lpath.value;
1062 apdu.datalen = pathlen;
1063
1064 apdu.resp = rbuf;
1065 apdu.resplen = sizeof(rbuf);
1066 apdu.le = 256;
1067
1068 rv = sc_transmit_apdu(card, &apdu);
1069 LOG_TEST_GOTO_ERR(ctx, rv, "APDU transmit failed");
1070 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1071 if (rv == SC_ERROR_INCORRECT_PARAMETERS &&
1072 lpath.type == SC_PATH_TYPE_DF_NAME && apdu.p2 == 0x00) {
1073 sc_log(ctx, "Warning: SC_ERROR_INCORRECT_PARAMETERS for SC_PATH_TYPE_DF_NAME, try again with P2=0x0C");
1074 apdu.p2 = 0x0C;
1075 continue;
1076 }
1077
1078 if (ii) {
1079 /* 'SELECT AID' do not returned FCP. Try to emulate. */
1080 apdu.resplen = sizeof(rbuf);
1081 rv = iasecc_emulate_fcp(ctx, &apdu);
1082 LOG_TEST_GOTO_ERR(ctx, rv, "Failed to emulate DF FCP");
1083 }
1084
1085 break;
1086 }
1087
1088 /*
1089 * Using of the cached DF and EF can cause problems in the multi-thread environment.
1090 * FIXME: introduce config. option that invalidates this cache outside the locked card session,
1091 * (or invent something else)
1092 */
1093 if (rv == SC_ERROR_FILE_NOT_FOUND && cache_valid && df_from_cache) {
1094 sc_invalidate_cache(card);
1095 sc_log(ctx, "iasecc_select_file() file not found, retry without cached DF");
1096 if (file_out) {
1097 sc_file_free(*file_out);
1098 *file_out = NULL;
1099 }
1100 rv = iasecc_select_file(card, path, file_out);
1101 LOG_FUNC_RETURN(ctx, rv);
1102 }
1103
1104 LOG_TEST_GOTO_ERR(ctx, rv, "iasecc_select_file() check SW failed");
1105
1106 sc_log(ctx,
1107 "iasecc_select_file() apdu.resp %"SC_FORMAT_LEN_SIZE_T"u",
1108 apdu.resplen);
1109 if (apdu.resplen) {
1110 sc_log(ctx, "apdu.resp %02X:%02X:%02X...", apdu.resp[0], apdu.resp[1], apdu.resp[2]);
1111
1112 switch (apdu.resp[0]) {
1113 case 0x62:
1114 case 0x6F:
1115 file = sc_file_new();
1116 if (file == NULL) {
1117 if (file_out) {
1118 sc_file_free(*file_out);
1119 *file_out = NULL;
1120 }
1121 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
1122 }
1123 file->path = lpath;
1124
1125 rv = iasecc_process_fci(card, file, apdu.resp, apdu.resplen);
1126 if (rv) {
1127 sc_file_free(file);
1128 if (file_out) {
1129 sc_file_free(*file_out);
1130 *file_out = NULL;
1131 }
1132 LOG_FUNC_RETURN(ctx, rv);
1133 }
1134 break;
1135 default:
1136 if (file_out) {
1137 sc_file_free(*file_out);
1138 *file_out = NULL;
1139 }
1140 LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
1141 }
1142
1143 sc_log(ctx, "FileType %i", file->type);
1144 if (file->type == SC_FILE_TYPE_DF) {
1145 if (card->cache.valid) {
1146 sc_file_free(card->cache.current_df);
1147 }
1148 card->cache.current_df = NULL;
1149
1150 sc_file_dup(&card->cache.current_df, file);
1151 card->cache.valid = 1;
1152 }
1153 else {
1154 if (card->cache.valid) {
1155 sc_file_free(card->cache.current_ef);
1156 }
1157
1158 card->cache.current_ef = NULL;
1159
1160 sc_file_dup(&card->cache.current_ef, file);
1161 card->cache.valid = 1;
1162 }
1163
1164 if (file_out) {
1165 sc_file_free(*file_out);
1166 *file_out = file;
1167 }
1168 else {
1169 sc_file_free(file);
1170 }
1171 }
1172 else if (lpath.type == SC_PATH_TYPE_DF_NAME) {
1173 sc_file_free(card->cache.current_df);
1174 card->cache.current_df = NULL;
1175
1176 sc_file_free(card->cache.current_ef);
1177 card->cache.current_ef = NULL;
1178
1179 card->cache.valid = 1;
1180 }
1181 } while(0);
1182
1183 sc_print_cache(card);
1184 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1185 err:
1186 if (file_out) {
1187 sc_file_free(*file_out);
1188 *file_out = NULL;
1189 }
1190 return rv;
1191 }
1192
1193
1194 static int
iasecc_process_fci(struct sc_card * card,struct sc_file * file,const unsigned char * buf,size_t buflen)1195 iasecc_process_fci(struct sc_card *card, struct sc_file *file,
1196 const unsigned char *buf, size_t buflen)
1197 {
1198 struct sc_context *ctx = card->ctx;
1199 size_t taglen, offs, ii;
1200 int rv;
1201 const unsigned char *acls = NULL, *tag = NULL;
1202 unsigned char mask;
1203 unsigned char ops_DF[7] = {
1204 SC_AC_OP_DELETE, 0xFF, SC_AC_OP_ACTIVATE, SC_AC_OP_DEACTIVATE, 0xFF, SC_AC_OP_CREATE, 0xFF
1205 };
1206 unsigned char ops_EF[7] = {
1207 SC_AC_OP_DELETE, 0xFF, SC_AC_OP_ACTIVATE, SC_AC_OP_DEACTIVATE, 0xFF, SC_AC_OP_UPDATE, SC_AC_OP_READ
1208 };
1209
1210 LOG_FUNC_CALLED(ctx);
1211
1212 tag = sc_asn1_find_tag(ctx, buf, buflen, 0x6F, &taglen);
1213 sc_log(ctx, "processing FCI: 0x6F tag %p", tag);
1214 if (tag != NULL) {
1215 sc_log(ctx, " FCP length %"SC_FORMAT_LEN_SIZE_T"u", taglen);
1216 buf = tag;
1217 buflen = taglen;
1218 }
1219
1220 tag = sc_asn1_find_tag(ctx, buf, buflen, 0x62, &taglen);
1221 sc_log(ctx, "processing FCI: 0x62 tag %p", tag);
1222 if (tag != NULL) {
1223 sc_log(ctx, " FCP length %"SC_FORMAT_LEN_SIZE_T"u", taglen);
1224 buf = tag;
1225 buflen = taglen;
1226 }
1227
1228 rv = iso_ops->process_fci(card, file, buf, buflen);
1229 LOG_TEST_RET(ctx, rv, "ISO parse FCI failed");
1230 /*
1231 Gemalto: 6F 19 80 02 02 ED 82 01 01 83 02 B0 01 88 00 8C 07 7B 17 17 17 17 17 00 8A 01 05 90 00
1232 Sagem: 6F 17 62 15 80 02 00 7D 82 01 01 8C 02 01 00 83 02 2F 00 88 01 F0 8A 01 05 90 00
1233 Oberthur: 62 1B 80 02 05 DC 82 01 01 83 02 B0 01 88 00 A1 09 8C 07 7B 17 FF 17 17 17 00 8A 01 05 90 00
1234 */
1235
1236 sc_log(ctx, "iasecc_process_fci() type %i; let's parse file ACLs", file->type);
1237 tag = sc_asn1_find_tag(ctx, buf, buflen, IASECC_DOCP_TAG_ACLS, &taglen);
1238 if (tag)
1239 acls = sc_asn1_find_tag(ctx, tag, taglen, IASECC_DOCP_TAG_ACLS_CONTACT, &taglen);
1240 else
1241 acls = sc_asn1_find_tag(ctx, buf, buflen, IASECC_DOCP_TAG_ACLS_CONTACT, &taglen);
1242
1243 if (!acls) {
1244 sc_log(ctx,
1245 "ACLs not found in data(%"SC_FORMAT_LEN_SIZE_T"u) %s",
1246 buflen, sc_dump_hex(buf, buflen));
1247 LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "ACLs tag missing");
1248 }
1249
1250 sc_log(ctx, "ACLs(%"SC_FORMAT_LEN_SIZE_T"u) '%s'", taglen,
1251 sc_dump_hex(acls, taglen));
1252 mask = 0x40, offs = 1;
1253 for (ii = 0; ii < 7; ii++, mask /= 2) {
1254 unsigned char op = file->type == SC_FILE_TYPE_DF ? ops_DF[ii] : ops_EF[ii];
1255
1256 /* avoid any access to acls[offs] beyond the taglen */
1257 if (offs >= taglen) {
1258 sc_log(ctx, "Warning: Invalid offset reached during ACL parsing");
1259 break;
1260 }
1261 if (!(mask & acls[0]))
1262 continue;
1263
1264 sc_log(ctx, "ACLs mask 0x%X, offs %"SC_FORMAT_LEN_SIZE_T"u, op 0x%X, acls[offs] 0x%X", mask, offs, op, acls[offs]);
1265 if (op == 0xFF) {
1266 ;
1267 }
1268 else if (acls[offs] == 0) {
1269 sc_file_add_acl_entry(file, op, SC_AC_NONE, 0);
1270 }
1271 else if (acls[offs] == 0xFF) {
1272 sc_file_add_acl_entry(file, op, SC_AC_NEVER, 0);
1273 }
1274 else if ((acls[offs] & IASECC_SCB_METHOD_MASK) == IASECC_SCB_METHOD_USER_AUTH) {
1275 sc_file_add_acl_entry(file, op, SC_AC_SEN, acls[offs] & IASECC_SCB_METHOD_MASK_REF);
1276 }
1277 else if (acls[offs] & IASECC_SCB_METHOD_MASK) {
1278 sc_file_add_acl_entry(file, op, SC_AC_SCB, acls[offs]);
1279 }
1280 else {
1281 sc_log(ctx, "Warning: non supported SCB method: %X", acls[offs]);
1282 sc_file_add_acl_entry(file, op, SC_AC_NEVER, 0);
1283 }
1284
1285 offs++;
1286 }
1287
1288 LOG_FUNC_RETURN(ctx, 0);
1289 }
1290
1291
1292 static int
iasecc_fcp_encode(struct sc_card * card,struct sc_file * file,unsigned char * out,size_t out_len)1293 iasecc_fcp_encode(struct sc_card *card, struct sc_file *file, unsigned char *out, size_t out_len)
1294 {
1295 struct sc_context *ctx = card->ctx;
1296 unsigned char buf[0x80], type;
1297 unsigned char ops[7] = {
1298 SC_AC_OP_DELETE, 0xFF, SC_AC_OP_ACTIVATE, SC_AC_OP_DEACTIVATE, 0xFF, SC_AC_OP_UPDATE, SC_AC_OP_READ
1299 };
1300 unsigned char smbs[8];
1301 size_t ii, offs = 0, amb, mask, nn_smb;
1302
1303 LOG_FUNC_CALLED(ctx);
1304
1305 if (file->type == SC_FILE_TYPE_DF)
1306 type = IASECC_FCP_TYPE_DF;
1307 else
1308 type = IASECC_FCP_TYPE_EF;
1309
1310 buf[offs++] = IASECC_FCP_TAG_SIZE;
1311 buf[offs++] = 2;
1312 buf[offs++] = (file->size >> 8) & 0xFF;
1313 buf[offs++] = file->size & 0xFF;
1314
1315 buf[offs++] = IASECC_FCP_TAG_TYPE;
1316 buf[offs++] = 1;
1317 buf[offs++] = type;
1318
1319 buf[offs++] = IASECC_FCP_TAG_FID;
1320 buf[offs++] = 2;
1321 buf[offs++] = (file->id >> 8) & 0xFF;
1322 buf[offs++] = file->id & 0xFF;
1323
1324 buf[offs++] = IASECC_FCP_TAG_SFID;
1325 buf[offs++] = 0;
1326
1327 amb = 0, mask = 0x40, nn_smb = 0;
1328 for (ii = 0; ii < sizeof(ops); ii++, mask >>= 1) {
1329 const struct sc_acl_entry *entry;
1330
1331 if (ops[ii]==0xFF)
1332 continue;
1333
1334 entry = sc_file_get_acl_entry(file, ops[ii]);
1335 if (!entry)
1336 continue;
1337
1338 sc_log(ctx, "method %X; reference %X", entry->method, entry->key_ref);
1339 if (entry->method == SC_AC_NEVER)
1340 continue;
1341 else if (entry->method == SC_AC_NONE)
1342 smbs[nn_smb++] = 0x00;
1343 else if (entry->method == SC_AC_CHV)
1344 smbs[nn_smb++] = entry->key_ref | IASECC_SCB_METHOD_USER_AUTH;
1345 else if (entry->method == SC_AC_SEN)
1346 smbs[nn_smb++] = entry->key_ref | IASECC_SCB_METHOD_USER_AUTH;
1347 else if (entry->method == SC_AC_SCB)
1348 smbs[nn_smb++] = entry->key_ref;
1349 else if (entry->method == SC_AC_PRO)
1350 smbs[nn_smb++] = entry->key_ref | IASECC_SCB_METHOD_SM;
1351 else
1352 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Non supported AC method");
1353
1354 amb |= mask;
1355 sc_log(ctx,
1356 "%"SC_FORMAT_LEN_SIZE_T"u: AMB %"SC_FORMAT_LEN_SIZE_T"X; nn_smb %"SC_FORMAT_LEN_SIZE_T"u",
1357 ii, amb, nn_smb);
1358 }
1359
1360 /* TODO: Encode contactless ACLs and life cycle status for all IAS/ECC cards */
1361 if (card->type == SC_CARD_TYPE_IASECC_SAGEM ||
1362 card->type == SC_CARD_TYPE_IASECC_AMOS ) {
1363 unsigned char status = 0;
1364
1365 buf[offs++] = IASECC_FCP_TAG_ACLS;
1366 buf[offs++] = 2*(2 + 1 + nn_smb);
1367
1368 buf[offs++] = IASECC_FCP_TAG_ACLS_CONTACT;
1369 buf[offs++] = nn_smb + 1;
1370 buf[offs++] = amb;
1371 memcpy(buf + offs, smbs, nn_smb);
1372 offs += nn_smb;
1373
1374 /* Same ACLs for contactless */
1375 buf[offs++] = IASECC_FCP_TAG_ACLS_CONTACTLESS;
1376 buf[offs++] = nn_smb + 1;
1377 buf[offs++] = amb;
1378 memcpy(buf + offs, smbs, nn_smb);
1379 offs += nn_smb;
1380
1381 if (file->status == SC_FILE_STATUS_ACTIVATED)
1382 status = 0x05;
1383 else if (file->status == SC_FILE_STATUS_CREATION)
1384 status = 0x01;
1385
1386 if (status) {
1387 buf[offs++] = 0x8A;
1388 buf[offs++] = 0x01;
1389 buf[offs++] = status;
1390 }
1391 }
1392 else {
1393 buf[offs++] = IASECC_FCP_TAG_ACLS;
1394 buf[offs++] = 2 + 1 + nn_smb;
1395
1396 buf[offs++] = IASECC_FCP_TAG_ACLS_CONTACT;
1397 buf[offs++] = nn_smb + 1;
1398 buf[offs++] = amb;
1399 memcpy(buf + offs, smbs, nn_smb);
1400 offs += nn_smb;
1401 }
1402
1403 if (out) {
1404 if (out_len < offs)
1405 LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to encode FCP");
1406 memcpy(out, buf, offs);
1407 }
1408
1409 LOG_FUNC_RETURN(ctx, offs);
1410 }
1411
1412
1413 static int
iasecc_create_file(struct sc_card * card,struct sc_file * file)1414 iasecc_create_file(struct sc_card *card, struct sc_file *file)
1415 {
1416 struct sc_context *ctx = card->ctx;
1417 struct sc_apdu apdu;
1418 const struct sc_acl_entry *entry = NULL;
1419 unsigned char sbuf[0x100];
1420 size_t sbuf_len;
1421 int rv;
1422
1423 LOG_FUNC_CALLED(ctx);
1424 sc_print_cache(card);
1425
1426 if (file->type != SC_FILE_TYPE_WORKING_EF)
1427 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Creation of the file with of this type is not supported");
1428
1429 sbuf_len = iasecc_fcp_encode(card, file, sbuf + 2, sizeof(sbuf)-2);
1430 LOG_TEST_RET(ctx, sbuf_len, "FCP encode error");
1431
1432 sbuf[0] = IASECC_FCP_TAG;
1433 sbuf[1] = sbuf_len;
1434
1435 if (card->cache.valid && card->cache.current_df) {
1436 entry = sc_file_get_acl_entry(card->cache.current_df, SC_AC_OP_CREATE);
1437 if (!entry)
1438 LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "iasecc_create_file() 'CREATE' ACL not present");
1439
1440 sc_log(ctx, "iasecc_create_file() 'CREATE' method/reference %X/%X", entry->method, entry->key_ref);
1441 sc_log(ctx, "iasecc_create_file() create data: '%s'", sc_dump_hex(sbuf, sbuf_len + 2));
1442 if (entry->method == SC_AC_SCB && (entry->key_ref & IASECC_SCB_METHOD_SM)) {
1443 rv = iasecc_sm_create_file(card, entry->key_ref & IASECC_SCB_METHOD_MASK_REF, sbuf, sbuf_len + 2);
1444 LOG_TEST_RET(ctx, rv, "iasecc_create_file() SM create file error");
1445
1446 rv = iasecc_select_file(card, &file->path, NULL);
1447 LOG_FUNC_RETURN(ctx, rv);
1448
1449 }
1450 }
1451
1452 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0, 0);
1453 apdu.data = sbuf;
1454 apdu.datalen = sbuf_len + 2;
1455 apdu.lc = sbuf_len + 2;
1456
1457 rv = sc_transmit_apdu(card, &apdu);
1458 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1459 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1460 LOG_TEST_RET(ctx, rv, "iasecc_create_file() create file error");
1461
1462 rv = iasecc_select_file(card, &file->path, NULL);
1463 LOG_TEST_RET(ctx, rv, "Cannot select newly created file");
1464
1465 LOG_FUNC_RETURN(ctx, rv);
1466 }
1467
1468 static int
iasecc_get_challenge(struct sc_card * card,u8 * rnd,size_t len)1469 iasecc_get_challenge(struct sc_card *card, u8 * rnd, size_t len)
1470 {
1471 /* As IAS/ECC cannot handle other data length than 0x08 */
1472 u8 rbuf[8];
1473 size_t out_len;
1474 int r;
1475
1476 LOG_FUNC_CALLED(card->ctx);
1477
1478 r = iso_ops->get_challenge(card, rbuf, sizeof rbuf);
1479 LOG_TEST_RET(card->ctx, r, "GET CHALLENGE cmd failed");
1480
1481 if (len < (size_t) r) {
1482 out_len = len;
1483 } else {
1484 out_len = (size_t) r;
1485 }
1486 memcpy(rnd, rbuf, out_len);
1487
1488 LOG_FUNC_RETURN(card->ctx, (int) out_len);
1489 }
1490
1491
1492 static int
iasecc_logout(struct sc_card * card)1493 iasecc_logout(struct sc_card *card)
1494 {
1495 struct sc_context *ctx = card->ctx;
1496 struct sc_path path;
1497 int rv;
1498
1499 LOG_FUNC_CALLED(ctx);
1500 if (!card->ef_atr || !card->ef_atr->aid.len)
1501 return SC_SUCCESS;
1502
1503 memset(&path, 0, sizeof(struct sc_path));
1504 path.type = SC_PATH_TYPE_DF_NAME;
1505 memcpy(path.value, card->ef_atr->aid.value, card->ef_atr->aid.len);
1506 path.len = card->ef_atr->aid.len;
1507
1508 rv = iasecc_select_file(card, &path, NULL);
1509 sc_log(ctx, "Select ECC ROOT with the AID from EF.ATR: rv %i", rv);
1510
1511 LOG_FUNC_RETURN(ctx, rv);
1512 }
1513
1514
1515 static int
iasecc_finish(struct sc_card * card)1516 iasecc_finish(struct sc_card *card)
1517 {
1518 struct sc_context *ctx = card->ctx;
1519 struct iasecc_private_data *private_data = (struct iasecc_private_data *)card->drv_data;
1520 struct iasecc_se_info *se_info = private_data->se_info, *next;
1521
1522 LOG_FUNC_CALLED(ctx);
1523
1524 while (se_info) {
1525 sc_file_free(se_info->df);
1526 next = se_info->next;
1527 free(se_info);
1528 se_info = next;
1529 }
1530
1531 free(card->drv_data);
1532 card->drv_data = NULL;
1533
1534 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1535 }
1536
1537
1538 static int
iasecc_delete_file(struct sc_card * card,const struct sc_path * path)1539 iasecc_delete_file(struct sc_card *card, const struct sc_path *path)
1540 {
1541 struct sc_context *ctx = card->ctx;
1542 const struct sc_acl_entry *entry = NULL;
1543 struct sc_apdu apdu;
1544 struct sc_file *file = NULL;
1545 int rv;
1546
1547 LOG_FUNC_CALLED(ctx);
1548 sc_print_cache(card);
1549
1550 rv = iasecc_select_file(card, path, &file);
1551 if (rv == SC_ERROR_FILE_NOT_FOUND)
1552 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
1553 LOG_TEST_RET(ctx, rv, "Cannot select file to delete");
1554
1555 entry = sc_file_get_acl_entry(file, SC_AC_OP_DELETE);
1556 if (!entry)
1557 LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "Cannot delete file: no 'DELETE' acl");
1558
1559 sc_log(ctx, "DELETE method/reference %X/%X", entry->method, entry->key_ref);
1560 if (entry->method == SC_AC_SCB && (entry->key_ref & IASECC_SCB_METHOD_SM)) {
1561 unsigned char se_num = (entry->method == SC_AC_SCB) ? (entry->key_ref & IASECC_SCB_METHOD_MASK_REF) : 0;
1562 rv = iasecc_sm_delete_file(card, se_num, file->id);
1563 }
1564 else {
1565 sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00);
1566
1567 rv = sc_transmit_apdu(card, &apdu);
1568 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1569 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1570 LOG_TEST_RET(ctx, rv, "Delete file failed");
1571
1572 if (card->cache.valid) {
1573 sc_file_free(card->cache.current_ef);
1574 }
1575 card->cache.current_ef = NULL;
1576 }
1577
1578 sc_file_free(file);
1579 LOG_FUNC_RETURN(ctx, rv);
1580 }
1581
1582
1583 static int
iasecc_check_sw(struct sc_card * card,unsigned int sw1,unsigned int sw2)1584 iasecc_check_sw(struct sc_card *card, unsigned int sw1, unsigned int sw2)
1585 {
1586 if (sw1 == 0x62 && sw2 == 0x82)
1587 return SC_SUCCESS;
1588
1589 return iso_ops->check_sw(card, sw1, sw2);
1590 }
1591
1592
1593 static unsigned
iasecc_get_algorithm(struct sc_context * ctx,const struct sc_security_env * env,unsigned operation,unsigned mechanism)1594 iasecc_get_algorithm(struct sc_context *ctx, const struct sc_security_env *env,
1595 unsigned operation, unsigned mechanism)
1596 {
1597 const struct sc_supported_algo_info *info = NULL;
1598 int ii;
1599
1600 if (!env)
1601 return 0;
1602
1603 for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && env->supported_algos[ii].reference; ii++)
1604 if ((env->supported_algos[ii].operations & operation)
1605 && (env->supported_algos[ii].mechanism == mechanism))
1606 break;
1607
1608 if (ii < SC_MAX_SUPPORTED_ALGORITHMS && env->supported_algos[ii].reference) {
1609 info = &env->supported_algos[ii];
1610 sc_log(ctx, "found IAS/ECC algorithm %X:%X:%X:%X",
1611 info->reference, info->mechanism, info->operations, info->algo_ref);
1612 }
1613 else {
1614 sc_log(ctx, "cannot find IAS/ECC algorithm (operation:%X,mechanism:%X)", operation, mechanism);
1615 }
1616
1617 return info ? info->algo_ref : 0;
1618 }
1619
1620
1621 static int
iasecc_se_cache_info(struct sc_card * card,struct iasecc_se_info * se)1622 iasecc_se_cache_info(struct sc_card *card, struct iasecc_se_info *se)
1623 {
1624 struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data;
1625 struct sc_context *ctx = card->ctx;
1626 struct iasecc_se_info *se_info = NULL, *si = NULL;
1627 int rv;
1628
1629 LOG_FUNC_CALLED(ctx);
1630
1631 se_info = calloc(1, sizeof(struct iasecc_se_info));
1632 if (!se_info)
1633 LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "SE info allocation error");
1634 memcpy(se_info, se, sizeof(struct iasecc_se_info));
1635
1636 if (card->cache.valid && card->cache.current_df) {
1637 sc_file_dup(&se_info->df, card->cache.current_df);
1638 if (se_info->df == NULL) {
1639 free(se_info);
1640 LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file");
1641 }
1642 }
1643
1644 rv = iasecc_docp_copy(ctx, &se->docp, &se_info->docp);
1645 if (rv < 0) {
1646 free(se_info->df);
1647 free(se_info);
1648 LOG_TEST_RET(ctx, rv, "Cannot make copy of DOCP");
1649 }
1650
1651 if (!prv->se_info) {
1652 prv->se_info = se_info;
1653 }
1654 else {
1655 for (si = prv->se_info; si->next; si = si->next)
1656 ;
1657 si->next = se_info;
1658 }
1659
1660 LOG_FUNC_RETURN(ctx, rv);
1661 }
1662
1663
1664 static int
iasecc_se_get_info_from_cache(struct sc_card * card,struct iasecc_se_info * se)1665 iasecc_se_get_info_from_cache(struct sc_card *card, struct iasecc_se_info *se)
1666 {
1667 struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data;
1668 struct sc_context *ctx = card->ctx;
1669 struct iasecc_se_info *si = NULL;
1670 int rv;
1671
1672 LOG_FUNC_CALLED(ctx);
1673
1674 for(si = prv->se_info; si; si = si->next) {
1675 if (si->reference != se->reference)
1676 continue;
1677 if (!(card->cache.valid && card->cache.current_df) && si->df)
1678 continue;
1679 if (card->cache.valid && card->cache.current_df && !si->df)
1680 continue;
1681 if (card->cache.valid && card->cache.current_df && si->df)
1682 if (memcmp(&card->cache.current_df->path, &si->df->path, sizeof(struct sc_path)))
1683 continue;
1684 break;
1685 }
1686
1687 if (!si)
1688 return SC_ERROR_OBJECT_NOT_FOUND;
1689
1690 memcpy(se, si, sizeof(struct iasecc_se_info));
1691
1692 if (si->df) {
1693 sc_file_dup(&se->df, si->df);
1694 if (se->df == NULL)
1695 LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot duplicate current DF file");
1696 }
1697
1698 rv = iasecc_docp_copy(ctx, &si->docp, &se->docp);
1699 LOG_TEST_RET(ctx, rv, "Cannot make copy of DOCP");
1700
1701 LOG_FUNC_RETURN(ctx, rv);
1702 }
1703
1704
1705 int
iasecc_se_get_info(struct sc_card * card,struct iasecc_se_info * se)1706 iasecc_se_get_info(struct sc_card *card, struct iasecc_se_info *se)
1707 {
1708 struct sc_context *ctx = card->ctx;
1709 struct sc_apdu apdu;
1710 unsigned char rbuf[0x100];
1711 unsigned char sbuf_iasecc[10] = {
1712 0x4D, 0x08, IASECC_SDO_TEMPLATE_TAG, 0x06,
1713 IASECC_SDO_TAG_HEADER, IASECC_SDO_CLASS_SE | IASECC_OBJECT_REF_LOCAL,
1714 se->reference & 0x3F,
1715 0x02, IASECC_SDO_CLASS_SE, 0x80
1716 };
1717 int rv;
1718
1719 LOG_FUNC_CALLED(ctx);
1720
1721 if (iasecc_is_cpx(card)) {
1722 rv = iasecc_select_mf(card, NULL);
1723 LOG_TEST_RET(ctx, rv, "MF invalid");
1724 }
1725
1726 if (se->reference > IASECC_SE_REF_MAX)
1727 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1728
1729 rv = iasecc_se_get_info_from_cache(card, se);
1730 if (rv == SC_ERROR_OBJECT_NOT_FOUND) {
1731 sc_log(ctx, "No SE#%X info in cache, try to use 'GET DATA'", se->reference);
1732
1733 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xCB, 0x3F, 0xFF);
1734 apdu.data = sbuf_iasecc;
1735 apdu.datalen = sizeof(sbuf_iasecc);
1736 apdu.lc = apdu.datalen;
1737 apdu.resp = rbuf;
1738 apdu.resplen = sizeof(rbuf);
1739 apdu.le = sizeof(rbuf);
1740
1741 rv = sc_transmit_apdu(card, &apdu);
1742 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1743 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1744 LOG_TEST_RET(ctx, rv, "get SE data error");
1745
1746 rv = iasecc_se_parse(card, apdu.resp, apdu.resplen, se);
1747 LOG_TEST_RET(ctx, rv, "cannot parse SE data");
1748
1749 rv = iasecc_se_cache_info(card, se);
1750 LOG_TEST_RET(ctx, rv, "failed to put SE data into cache");
1751 }
1752
1753 LOG_FUNC_RETURN(ctx, rv);
1754 }
1755
1756
1757 static int
iasecc_set_security_env(struct sc_card * card,const struct sc_security_env * env,int se_num)1758 iasecc_set_security_env(struct sc_card *card,
1759 const struct sc_security_env *env, int se_num)
1760 {
1761 struct sc_context *ctx = card->ctx;
1762 struct iasecc_sdo sdo;
1763 struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data;
1764 unsigned algo_ref;
1765 struct sc_apdu apdu;
1766 unsigned sign_meth, sign_ref, auth_meth, auth_ref, aflags;
1767 unsigned char cse_crt_at[] = {
1768 0x84, 0x01, 0xFF,
1769 0x80, 0x01, IASECC_ALGORITHM_RSA_PKCS
1770 };
1771 unsigned char cse_crt_dst[] = {
1772 0x84, 0x01, 0xFF,
1773 0x80, 0x01, (IASECC_ALGORITHM_RSA_PKCS | IASECC_ALGORITHM_SHA1)
1774 };
1775 unsigned char cse_crt_ht[] = {
1776 0x80, 0x01, IASECC_ALGORITHM_SHA1
1777 };
1778 unsigned char cse_crt_ct[] = {
1779 0x84, 0x01, 0xFF,
1780 0x80, 0x01, (IASECC_ALGORITHM_RSA_PKCS_DECRYPT | IASECC_ALGORITHM_SHA1)
1781 };
1782 int rv, operation = env->operation;
1783
1784 /* TODO: take algorithm references from 5032, not from header file. */
1785 LOG_FUNC_CALLED(ctx);
1786 sc_log(ctx, "iasecc_set_security_env(card:%p) operation 0x%X; senv.algorithm 0x%X, senv.algorithm_ref 0x%X",
1787 card, env->operation, env->algorithm, env->algorithm_ref);
1788
1789 memset(&sdo, 0, sizeof(sdo));
1790 sdo.sdo_class = IASECC_SDO_CLASS_RSA_PRIVATE;
1791 sdo.sdo_ref = env->key_ref[0] & ~IASECC_OBJECT_REF_LOCAL;
1792 rv = iasecc_sdo_get_data(card, &sdo);
1793 LOG_TEST_RET(ctx, rv, "Cannot get RSA PRIVATE SDO data");
1794
1795 /* To made by iasecc_sdo_convert_to_file() */
1796 prv->key_size = *(sdo.docp.size.value + 0) * 0x100 + *(sdo.docp.size.value + 1);
1797 sc_log(ctx, "prv->key_size 0x%"SC_FORMAT_LEN_SIZE_T"X", prv->key_size);
1798
1799 rv = iasecc_sdo_convert_acl(card, &sdo, SC_AC_OP_PSO_COMPUTE_SIGNATURE, &sign_meth, &sign_ref);
1800 LOG_TEST_RET(ctx, rv, "Cannot convert SC_AC_OP_SIGN acl");
1801
1802 rv = iasecc_sdo_convert_acl(card, &sdo, SC_AC_OP_INTERNAL_AUTHENTICATE, &auth_meth, &auth_ref);
1803 LOG_TEST_RET(ctx, rv, "Cannot convert SC_AC_OP_INT_AUTH acl");
1804
1805 aflags = env->algorithm_flags;
1806
1807 if (!(aflags & SC_ALGORITHM_RSA_PAD_PKCS1))
1808 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Only supported signature with PKCS1 padding");
1809
1810 if (operation == SC_SEC_OPERATION_SIGN) {
1811 if (!(aflags & (SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_HASH_SHA256))) {
1812 sc_log(ctx, "CKM_RSA_PKCS asked -- use 'AUTHENTICATE' sign operation instead of 'SIGN'");
1813 operation = SC_SEC_OPERATION_AUTHENTICATE;
1814 }
1815 else if (sign_meth == SC_AC_NEVER) {
1816 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "PSO_DST not allowed for this key");
1817 }
1818 }
1819
1820 if (operation == SC_SEC_OPERATION_SIGN) {
1821 prv->op_method = sign_meth;
1822 prv->op_ref = sign_ref;
1823 }
1824 else if (operation == SC_SEC_OPERATION_AUTHENTICATE) {
1825 if (auth_meth == SC_AC_NEVER)
1826 LOG_TEST_RET(ctx, SC_ERROR_NOT_ALLOWED, "INTERNAL_AUTHENTICATE is not allowed for this key");
1827
1828 prv->op_method = auth_meth;
1829 prv->op_ref = auth_ref;
1830 }
1831
1832 sc_log(ctx, "senv.algorithm 0x%X, senv.algorithm_ref 0x%X", env->algorithm, env->algorithm_ref);
1833 sc_log(ctx,
1834 "se_num %i, operation 0x%X, algorithm 0x%X, algorithm_ref 0x%X, flags 0x%X; key size %"SC_FORMAT_LEN_SIZE_T"u",
1835 se_num, operation, env->algorithm, env->algorithm_ref,
1836 env->algorithm_flags, prv->key_size);
1837 switch (operation) {
1838 case SC_SEC_OPERATION_SIGN:
1839 if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1))
1840 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Need RSA_PKCS1 specified");
1841
1842 if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) {
1843 algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_HASH, CKM_SHA256);
1844 if (!algo_ref)
1845 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Card application do not supports HASH:SHA256");
1846
1847 cse_crt_ht[2] = algo_ref; /* IASECC_ALGORITHM_SHA2 */
1848
1849 algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE, CKM_SHA256_RSA_PKCS);
1850 if (!algo_ref)
1851 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Card application do not supports SIGNATURE:SHA1_RSA_PKCS");
1852
1853 cse_crt_dst[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL;
1854 cse_crt_dst[5] = algo_ref; /* IASECC_ALGORITHM_RSA_PKCS | IASECC_ALGORITHM_SHA2 */
1855 }
1856 else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) {
1857 algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_HASH, CKM_SHA_1);
1858 if (!algo_ref)
1859 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Card application do not supports HASH:SHA1");
1860
1861 cse_crt_ht[2] = algo_ref; /* IASECC_ALGORITHM_SHA1 */
1862
1863 algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE, CKM_SHA1_RSA_PKCS);
1864 if (!algo_ref)
1865 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Card application do not supports SIGNATURE:SHA1_RSA_PKCS");
1866
1867 cse_crt_dst[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL;
1868 cse_crt_dst[5] = algo_ref; /* IASECC_ALGORITHM_RSA_PKCS | IASECC_ALGORITHM_SHA1 */
1869 }
1870 else {
1871 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Need RSA_HASH_SHA[1,256] specified");
1872 }
1873
1874 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, IASECC_CRT_TAG_HT);
1875 apdu.data = cse_crt_ht;
1876 apdu.datalen = sizeof(cse_crt_ht);
1877 apdu.lc = sizeof(cse_crt_ht);
1878
1879 rv = sc_transmit_apdu(card, &apdu);
1880 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1881 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1882 LOG_TEST_RET(ctx, rv, "MSE restore error");
1883
1884 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, IASECC_CRT_TAG_DST);
1885 apdu.data = cse_crt_dst;
1886 apdu.datalen = sizeof(cse_crt_dst);
1887 apdu.lc = sizeof(cse_crt_dst);
1888 break;
1889 case SC_SEC_OPERATION_AUTHENTICATE:
1890 algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_COMPUTE_SIGNATURE, CKM_RSA_PKCS);
1891 if (!algo_ref)
1892 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Application do not supports SIGNATURE:RSA_PKCS");
1893
1894 cse_crt_at[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL;
1895 cse_crt_at[5] = algo_ref; /* IASECC_ALGORITHM_RSA_PKCS */
1896
1897 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, IASECC_CRT_TAG_AT);
1898 apdu.data = cse_crt_at;
1899 apdu.datalen = sizeof(cse_crt_at);
1900 apdu.lc = sizeof(cse_crt_at);
1901 break;
1902 case SC_SEC_OPERATION_DECIPHER:
1903 rv = iasecc_sdo_convert_acl(card, &sdo, SC_AC_OP_PSO_DECRYPT, &prv->op_method, &prv->op_ref);
1904 LOG_TEST_RET(ctx, rv, "Cannot convert SC_AC_OP_PSO_DECRYPT acl");
1905 algo_ref = iasecc_get_algorithm(ctx, env, SC_PKCS15_ALGO_OP_DECIPHER, CKM_RSA_PKCS);
1906 if (!algo_ref)
1907 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Application do not supports DECIPHER:RSA_PKCS");
1908
1909 cse_crt_ct[2] = env->key_ref[0] | IASECC_OBJECT_REF_LOCAL;
1910 cse_crt_ct[5] = algo_ref; /* IASECC_ALGORITHM_RSA_PKCS_DECRYPT | IASECC_ALGORITHM_SHA1 */
1911
1912 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, IASECC_CRT_TAG_CT);
1913 apdu.data = cse_crt_ct;
1914 apdu.datalen = sizeof(cse_crt_ct);
1915 apdu.lc = sizeof(cse_crt_ct);
1916 break;
1917 default:
1918 LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
1919 }
1920
1921 rv = sc_transmit_apdu(card, &apdu);
1922 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
1923 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
1924 LOG_TEST_RET(ctx, rv, "MSE restore error");
1925
1926 prv->security_env = *env;
1927 prv->security_env.operation = operation;
1928
1929 LOG_FUNC_RETURN(ctx, 0);
1930 }
1931
1932
1933 static int
iasecc_chv_verify(struct sc_card * card,struct sc_pin_cmd_data * pin_cmd,unsigned char * scbs,int * tries_left)1934 iasecc_chv_verify(struct sc_card *card, struct sc_pin_cmd_data *pin_cmd, unsigned char *scbs,
1935 int *tries_left)
1936 {
1937 struct sc_context *ctx = card->ctx;
1938 unsigned char scb = scbs[IASECC_ACLS_CHV_VERIFY];
1939 int rv;
1940
1941 LOG_FUNC_CALLED(ctx);
1942 sc_log(ctx, "Verify CHV PIN(ref:%i,len:%i,scb:%X)", pin_cmd->pin_reference, pin_cmd->pin1.len,
1943 scb);
1944
1945 if (scb & IASECC_SCB_METHOD_SM) {
1946 rv = iasecc_sm_pin_verify(card, scb & IASECC_SCB_METHOD_MASK_REF, pin_cmd, tries_left);
1947 LOG_FUNC_RETURN(ctx, rv);
1948 }
1949
1950 rv = iso_ops->pin_cmd(card, pin_cmd, tries_left);
1951 LOG_FUNC_RETURN(ctx, rv);
1952 }
1953
1954
1955 static int
iasecc_se_at_to_chv_reference(struct sc_card * card,unsigned reference,unsigned * chv_reference)1956 iasecc_se_at_to_chv_reference(struct sc_card *card, unsigned reference,
1957 unsigned *chv_reference)
1958 {
1959 struct sc_context *ctx = card->ctx;
1960 struct iasecc_se_info se;
1961 struct sc_crt crt;
1962 int rv;
1963
1964 LOG_FUNC_CALLED(ctx);
1965 sc_log(ctx, "SE reference %i", reference);
1966
1967 if (reference > IASECC_SE_REF_MAX)
1968 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
1969
1970 memset(&se, 0, sizeof(se));
1971 se.reference = reference;
1972
1973 rv = iasecc_se_get_info(card, &se);
1974 LOG_TEST_RET(ctx, rv, "SDO get data error");
1975
1976 memset(&crt, 0, sizeof(crt));
1977 crt.tag = IASECC_CRT_TAG_AT;
1978 crt.usage = IASECC_UQB_AT_USER_PASSWORD;
1979
1980 rv = iasecc_se_get_crt(card, &se, &crt);
1981 LOG_TEST_RET(ctx, rv, "no authentication template for USER PASSWORD");
1982
1983 if (chv_reference)
1984 *chv_reference = crt.refs[0];
1985
1986 sc_file_free(se.df);
1987
1988 LOG_FUNC_RETURN(ctx, rv);
1989 }
1990
1991
1992 static int
iasecc_pin_get_status(struct sc_card * card,struct sc_pin_cmd_data * data,int * tries_left)1993 iasecc_pin_get_status(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
1994 {
1995 struct sc_context *ctx = card->ctx;
1996 struct sc_pin_cmd_data info;
1997 int rv;
1998
1999 LOG_FUNC_CALLED(ctx);
2000
2001 if (data->pin_type != SC_AC_CHV)
2002 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "PIN type is not supported for status");
2003
2004 memset(&info, 0, sizeof(info));
2005 info.cmd = SC_PIN_CMD_GET_INFO;
2006 info.pin_type = data->pin_type;
2007 info.pin_reference = data->pin_reference;
2008
2009 rv = iso_ops->pin_cmd(card, &info, tries_left);
2010 LOG_TEST_RET(ctx, rv, "Failed to get PIN info");
2011
2012 data->pin1.max_tries = info.pin1.max_tries;
2013 data->pin1.tries_left = info.pin1.tries_left;
2014 data->pin1.logged_in = info.pin1.logged_in;
2015
2016 LOG_FUNC_RETURN(ctx, rv);
2017 }
2018
2019
2020 static int
iasecc_pin_verify(struct sc_card * card,struct sc_pin_cmd_data * data,int * tries_left)2021 iasecc_pin_verify(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2022 {
2023 struct sc_context *ctx = card->ctx;
2024 unsigned type = data->pin_type;
2025 unsigned reference = data->pin_reference;
2026 struct sc_pin_cmd_data pin_cmd;
2027 struct iasecc_pin_policy policy;
2028 int tries_before_verify = -1;
2029 int rv;
2030
2031 LOG_FUNC_CALLED(ctx);
2032 sc_log(ctx,
2033 "Verify PIN(type:%X,ref:%i,data(len:%i,%p)",
2034 type, reference, data->pin1.len, data->pin1.data);
2035
2036 if (type == SC_AC_AUT) {
2037 rv = iasecc_sm_external_authentication(card, reference, tries_left);
2038 LOG_FUNC_RETURN(ctx, rv);
2039 }
2040
2041 if (type == SC_AC_SCB) {
2042 if (reference & IASECC_SCB_METHOD_USER_AUTH) {
2043 type = SC_AC_SEN;
2044 reference = reference & IASECC_SCB_METHOD_MASK_REF;
2045 }
2046 }
2047
2048 if (type == SC_AC_SEN) {
2049 type = SC_AC_CHV;
2050 rv = iasecc_se_at_to_chv_reference(card, reference, &reference);
2051 LOG_TEST_RET(ctx, rv, "SE AT to CHV reference error");
2052 }
2053
2054 if (type != SC_AC_CHV) {
2055 sc_log(ctx, "Do not try to verify non CHV PINs");
2056 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2057 }
2058
2059 pin_cmd = *data;
2060 pin_cmd.pin_type = SC_AC_CHV;
2061 pin_cmd.pin_reference = reference;
2062 pin_cmd.cmd = SC_PIN_CMD_VERIFY;
2063
2064 rv = iasecc_pin_get_status(card, &pin_cmd, tries_left);
2065 if (data->pin1.data && !data->pin1.len)
2066 LOG_FUNC_RETURN(ctx, rv);
2067
2068 if (!rv) {
2069 if (pin_cmd.pin1.logged_in == SC_PIN_STATE_LOGGED_IN)
2070 if (iasecc_chv_cache_is_verified(card, &pin_cmd))
2071 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2072 }
2073 else if (rv != SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
2074 LOG_FUNC_RETURN(ctx, rv);
2075 }
2076
2077 iasecc_chv_cache_clean(card, &pin_cmd);
2078
2079 rv = iasecc_pin_merge_policy(card, &pin_cmd, &pin_cmd.pin1, &policy);
2080 LOG_TEST_RET(ctx, rv, "Failed to update PIN1 info");
2081
2082 /* PIN-pads work best with fixed-size lengths. Use PIN padding when length is available. */
2083 if (pin_cmd.flags & SC_PIN_CMD_USE_PINPAD) {
2084 tries_before_verify = pin_cmd.pin1.tries_left;
2085 if (policy.stored_length > 0)
2086 iasecc_set_pin_padding(&pin_cmd, &pin_cmd.pin1, policy.stored_length);
2087 }
2088
2089 rv = iasecc_chv_verify(card, &pin_cmd, policy.scbs, tries_left);
2090
2091 /*
2092 * Detect and log PIN-pads which don't handle variable-length PIN - special case where they
2093 * forward the CHV verify command with Lc = 0 to the card, without updating Lc. An IAS-ECC
2094 * card responds to this command by returning the number of attempts left, without
2095 * decreasing the counter.
2096 */
2097 if ((pin_cmd.flags & SC_PIN_CMD_USE_PINPAD) && !(pin_cmd.flags & SC_PIN_CMD_NEED_PADDING)) {
2098 if (rv == SC_ERROR_PIN_CODE_INCORRECT && pin_cmd.pin1.tries_left == tries_before_verify) {
2099 SC_TEST_RET(ctx, SC_LOG_DEBUG_VERBOSE, rv,
2100 "PIN-pad reader does not support variable-length PIN");
2101 }
2102 }
2103
2104 LOG_TEST_RET(ctx, rv, "PIN CHV verification error");
2105
2106 rv = iasecc_chv_cache_verified(card, &pin_cmd);
2107
2108 LOG_FUNC_RETURN(ctx, rv);
2109 }
2110
2111
2112 static int
iasecc_pin_get_policy(struct sc_card * card,struct sc_pin_cmd_data * data,struct iasecc_pin_policy * pin)2113 iasecc_pin_get_policy (struct sc_card *card, struct sc_pin_cmd_data *data, struct iasecc_pin_policy *pin)
2114 {
2115 struct sc_context *ctx = card->ctx;
2116 struct sc_file *save_current_df = NULL, *save_current_ef = NULL;
2117 struct iasecc_sdo sdo;
2118 struct sc_path path;
2119 int rv;
2120
2121 LOG_FUNC_CALLED(ctx);
2122 sc_log(ctx, "iasecc_pin_get_policy(card:%p)", card);
2123
2124 if (data->pin_type != SC_AC_CHV) {
2125 sc_log(ctx, "PIN policy only available for CHV type");
2126 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
2127 }
2128
2129 if (card->cache.valid && card->cache.current_df) {
2130 sc_file_dup(&save_current_df, card->cache.current_df);
2131 if (save_current_df == NULL) {
2132 rv = SC_ERROR_OUT_OF_MEMORY;
2133 sc_log(ctx, "Cannot duplicate current DF file");
2134 goto err;
2135 }
2136 }
2137
2138 if (card->cache.valid && card->cache.current_ef) {
2139 sc_file_dup(&save_current_ef, card->cache.current_ef);
2140 if (save_current_ef == NULL) {
2141 rv = SC_ERROR_OUT_OF_MEMORY;
2142 sc_log(ctx, "Cannot duplicate current EF file");
2143 goto err;
2144 }
2145 }
2146
2147 if (!(data->pin_reference & IASECC_OBJECT_REF_LOCAL) && card->cache.valid && card->cache.current_df) {
2148 sc_format_path("3F00", &path);
2149 path.type = SC_PATH_TYPE_FILE_ID;
2150 rv = iasecc_select_file(card, &path, NULL);
2151 LOG_TEST_GOTO_ERR(ctx, rv, "Unable to select MF");
2152 }
2153
2154 memset(&sdo, 0, sizeof(sdo));
2155 sdo.sdo_class = IASECC_SDO_CLASS_CHV;
2156
2157 sdo.sdo_ref = data->pin_reference & ~IASECC_OBJECT_REF_LOCAL;
2158
2159 sc_log(ctx, "iasecc_pin_get_policy() reference %i", sdo.sdo_ref);
2160
2161 rv = iasecc_sdo_get_data(card, &sdo);
2162 LOG_TEST_GOTO_ERR(ctx, rv, "Cannot get SDO PIN data");
2163
2164 if (sdo.docp.acls_contact.size == 0) {
2165 rv = SC_ERROR_INVALID_DATA;
2166 sc_log(ctx, "Extremely strange ... there is no ACLs");
2167 goto err;
2168 }
2169
2170 sc_log(ctx,
2171 "iasecc_pin_get_policy() sdo.docp.size.size %"SC_FORMAT_LEN_SIZE_T"u",
2172 sdo.docp.size.size);
2173
2174 memcpy(pin->scbs, sdo.docp.scbs, sizeof(pin->scbs));
2175
2176 pin->min_length = (sdo.data.chv.size_min.value ? *sdo.data.chv.size_min.value : -1);
2177 pin->max_length = (sdo.data.chv.size_max.value ? *sdo.data.chv.size_max.value : -1);
2178 pin->tries_maximum = (sdo.docp.tries_maximum.value ? *sdo.docp.tries_maximum.value : -1);
2179 pin->tries_remaining = (sdo.docp.tries_remaining.value ? *sdo.docp.tries_remaining.value : -1);
2180 if (sdo.docp.size.value && sdo.docp.size.size <= sizeof(int)) {
2181 unsigned int n = 0;
2182 unsigned int i;
2183 for (i=0; i<sdo.docp.size.size; i++)
2184 n = (n << 8) + *(sdo.docp.size.value + i);
2185 pin->stored_length = n;
2186 } else {
2187 pin->stored_length = -1;
2188 }
2189
2190 sc_log(ctx, "PIN policy: size max/min %i/%i, tries max/left %i/%i",
2191 pin->max_length, pin->min_length, pin->tries_maximum, pin->tries_remaining);
2192 iasecc_sdo_free_fields(card, &sdo);
2193
2194 if (save_current_df) {
2195 sc_log(ctx, "iasecc_pin_get_policy() restore current DF");
2196 rv = iasecc_select_file(card, &save_current_df->path, NULL);
2197 LOG_TEST_GOTO_ERR(ctx, rv, "Cannot return to saved DF");
2198 }
2199
2200 if (save_current_ef) {
2201 sc_log(ctx, "iasecc_pin_get_policy() restore current EF");
2202 rv = iasecc_select_file(card, &save_current_ef->path, NULL);
2203 LOG_TEST_GOTO_ERR(ctx, rv, "Cannot return to saved EF");
2204 }
2205
2206 err:
2207 sc_file_free(save_current_df);
2208 sc_file_free(save_current_ef);
2209
2210 LOG_FUNC_RETURN(ctx, rv);
2211 }
2212
2213
2214 static int
iasecc_pin_get_info(struct sc_card * card,struct sc_pin_cmd_data * data,int * tries_left)2215 iasecc_pin_get_info(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2216 {
2217 struct sc_context *ctx = card->ctx;
2218 struct iasecc_pin_policy policy;
2219 int rv;
2220
2221 LOG_FUNC_CALLED(ctx);
2222 sc_log(ctx, "iasecc_pin_get_info(card:%p)", card);
2223
2224 /*
2225 * Get PIN status first and thereafter update with info from PIN policy, when available.
2226 * The first one is typically used for the PIN verification status and number of remaining
2227 * tries, and the second one for the maximum tries. If a field is present in both, the
2228 * policy takes precedence.
2229 */
2230 rv = iasecc_pin_get_status(card, data, tries_left);
2231 LOG_TEST_RET(ctx, rv, "Failed to get PIN status");
2232
2233 rv = iasecc_pin_get_policy(card, data, &policy);
2234 LOG_TEST_RET(ctx, rv, "Failed to get PIN policy");
2235
2236 /*
2237 * We only care about the tries_xxx fields in the PIN policy, since the other ones are not
2238 * commonly expected or used in a SC_PIN_CMD_GET_INFO response. Note that max_tries is
2239 * always taken from the policy, since it is never expected to be available in status (it
2240 * is set to -1 when not available in policy).
2241 */
2242 data->pin1.max_tries = policy.tries_maximum;
2243 if (policy.tries_remaining >= 0)
2244 data->pin1.tries_left = policy.tries_remaining;
2245
2246 if (tries_left)
2247 *tries_left = data->pin1.tries_left;
2248
2249 LOG_FUNC_RETURN(ctx, rv);
2250 }
2251
2252
2253 /*
2254 * Check PIN and update flags. We reject empty PINs (where data is non-NULL but length is 0) due
2255 * to their non-obvious meaning in verification/change/unblock. We also need to update the
2256 * SC_PIN_CMD_USE_PINPAD flag depending on the PIN being available or not (where data is NULL means
2257 * that PIN is not available). Unfortunately we can not rely on the flag provided by the caller due
2258 * to its ambiguous use. The approach here is to assume pin-pad input when the PIN data is NULL,
2259 * otherwise not.
2260 */
iasecc_check_update_pin(struct sc_pin_cmd_data * data,struct sc_pin_cmd_pin * pin)2261 static int iasecc_check_update_pin(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin)
2262 {
2263 if ((!pin->data && pin->len) || (pin->data && !pin->len))
2264 return SC_ERROR_INVALID_ARGUMENTS;
2265
2266 if (pin->data)
2267 data->flags &= ~SC_PIN_CMD_USE_PINPAD;
2268 else
2269 data->flags |= SC_PIN_CMD_USE_PINPAD;
2270
2271 return SC_SUCCESS;
2272 }
2273
2274
2275 /* Enable PIN padding with 0xff as the padding character, unless already enabled */
iasecc_set_pin_padding(struct sc_pin_cmd_data * data,struct sc_pin_cmd_pin * pin,size_t pad_len)2276 static void iasecc_set_pin_padding(struct sc_pin_cmd_data *data, struct sc_pin_cmd_pin *pin,
2277 size_t pad_len)
2278 {
2279 if (data->flags & SC_PIN_CMD_NEED_PADDING)
2280 return;
2281
2282 pin->pad_length = pad_len;
2283 pin->pad_char = 0xff;
2284 data->flags |= SC_PIN_CMD_NEED_PADDING;
2285 }
2286
2287
2288 /*
2289 * Retrieve the PIN policy and combine it with the existing fields in an intelligent way. This is
2290 * needed since we may be called with existing settings, typically from the PKCS #15 layer. We use
2291 * the IAS-ECC card-level PIN settings as complementary.
2292 */
2293 static int
iasecc_pin_merge_policy(struct sc_card * card,struct sc_pin_cmd_data * data,struct sc_pin_cmd_pin * pin,struct iasecc_pin_policy * policy)2294 iasecc_pin_merge_policy(struct sc_card *card, struct sc_pin_cmd_data *data,
2295 struct sc_pin_cmd_pin *pin, struct iasecc_pin_policy *policy)
2296 {
2297 struct sc_context *ctx = card->ctx;
2298 size_t pad_len = 0;
2299 int rv;
2300
2301 LOG_FUNC_CALLED(ctx);
2302 sc_log(ctx, "iasecc_pin_merge_policy(card:%p)", card);
2303
2304 rv = iasecc_check_update_pin(data, pin);
2305 LOG_TEST_RET(ctx, rv, "Invalid PIN");
2306
2307 rv = iasecc_pin_get_policy(card, data, policy);
2308 LOG_TEST_RET(ctx, rv, "Failed to get PIN policy");
2309
2310 /* Some cards obviously use the min/max length fields to signal PIN padding */
2311 if (policy->min_length > 0 && policy->min_length == policy->max_length) {
2312 pad_len = policy->min_length;
2313 policy->min_length = 0;
2314 }
2315
2316 /* Take the most limited values of min/max lengths */
2317 if (policy->min_length > 0 && (size_t) policy->min_length > pin->min_length)
2318 pin->min_length = policy->min_length;
2319 if (policy->max_length > 0 && (!pin->max_length || (size_t) policy->max_length < pin->max_length))
2320 pin->max_length = policy->max_length;
2321
2322 /* Set PIN padding if needed and not already set by the caller */
2323 if (pad_len)
2324 iasecc_set_pin_padding(data, pin, pad_len);
2325
2326 LOG_FUNC_RETURN(ctx, rv);
2327 }
2328
2329
2330 static int
iasecc_keyset_change(struct sc_card * card,struct sc_pin_cmd_data * data,int * tries_left)2331 iasecc_keyset_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2332 {
2333 struct sc_context *ctx = card->ctx;
2334 struct iasecc_sdo_update update;
2335 struct iasecc_sdo sdo;
2336 unsigned scb;
2337 int rv;
2338
2339 LOG_FUNC_CALLED(ctx);
2340 sc_log(ctx, "Change keyset(ref:%i,lengths:%i)", data->pin_reference, data->pin2.len);
2341 if (!data->pin2.data || data->pin2.len < 32)
2342 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Needs at least 32 bytes for a new keyset value");
2343
2344 memset(&sdo, 0, sizeof(sdo));
2345 sdo.sdo_class = IASECC_SDO_CLASS_KEYSET;
2346 sdo.sdo_ref = data->pin_reference;
2347
2348 rv = iasecc_sdo_get_data(card, &sdo);
2349 LOG_TEST_RET(ctx, rv, "Cannot get keyset data");
2350
2351 if (sdo.docp.acls_contact.size == 0)
2352 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Bewildered ... there are no ACLs");
2353 scb = sdo.docp.scbs[IASECC_ACLS_KEYSET_PUT_DATA];
2354 iasecc_sdo_free_fields(card, &sdo);
2355
2356 sc_log(ctx, "SCB:0x%X", scb);
2357 if (!(scb & IASECC_SCB_METHOD_SM))
2358 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Other then protected by SM, the keyset change is not supported");
2359
2360 memset(&update, 0, sizeof(update));
2361 update.magic = SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA;
2362 update.sdo_class = sdo.sdo_class;
2363 update.sdo_ref = sdo.sdo_ref;
2364
2365 update.fields[0].parent_tag = IASECC_SDO_KEYSET_TAG;
2366 update.fields[0].tag = IASECC_SDO_KEYSET_TAG_MAC;
2367 /* FIXME is it safe to modify the const value here? */
2368 update.fields[0].value = (unsigned char *) data->pin2.data;
2369 update.fields[0].size = 16;
2370
2371 update.fields[1].parent_tag = IASECC_SDO_KEYSET_TAG;
2372 update.fields[1].tag = IASECC_SDO_KEYSET_TAG_ENC;
2373 /* FIXME is it safe to modify the const value here? */
2374 update.fields[1].value = (unsigned char *) data->pin2.data + 16;
2375 update.fields[1].size = 16;
2376
2377 rv = iasecc_sm_sdo_update(card, (scb & IASECC_SCB_METHOD_MASK_REF), &update);
2378 LOG_FUNC_RETURN(ctx, rv);
2379 }
2380
2381
2382 /*
2383 * The PIN change function can handle different PIN-pad input combinations for the old and new
2384 * PINs:
2385 * OLD PIN: NEW PIN: DESCRIPTION:
2386 * Available Available No input.
2387 * Available Absent Only new PIN is input.
2388 * Absent Available Both PINs are input (due to limitations in IAS-ECC)
2389 * Absent Absent Both PINs are input.
2390 */
2391 static int
iasecc_pin_change(struct sc_card * card,struct sc_pin_cmd_data * data,int * tries_left)2392 iasecc_pin_change(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2393 {
2394 struct sc_context *ctx = card->ctx;
2395 struct sc_pin_cmd_data pin_cmd;
2396 struct iasecc_pin_policy policy;
2397 int rv;
2398
2399 LOG_FUNC_CALLED(ctx);
2400 sc_log(ctx, "Change PIN(ref:%i,type:0x%X,lengths:%i/%i)",
2401 data->pin_reference, data->pin_type, data->pin1.len, data->pin2.len);
2402
2403 if (data->pin_type != SC_AC_CHV) {
2404 sc_log(ctx, "Can not change non-CHV PINs");
2405 LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
2406 }
2407
2408 /*
2409 * Verify the original PIN. This would normally not be needed since it is implicitly done
2410 * by the card when executing a PIN change command. But we must go through our verification
2411 * function in order to handle secure messaging setup, if enabled for the PIN. The
2412 * verification is skipped for PIN-pads (which do not work with SM anyway), to avoid the
2413 * user having to enter the PIN twice.
2414 */
2415 pin_cmd = *data;
2416 pin_cmd.cmd = SC_PIN_CMD_VERIFY;
2417
2418 rv = iasecc_pin_merge_policy(card, &pin_cmd, &pin_cmd.pin1, &policy);
2419 LOG_TEST_RET(ctx, rv, "Failed to update PIN1 info");
2420
2421 if (!(pin_cmd.flags & SC_PIN_CMD_USE_PINPAD)) {
2422 rv = iasecc_chv_verify(card, &pin_cmd, policy.scbs, tries_left);
2423 LOG_TEST_RET(ctx, rv, "PIN CHV verification error");
2424 }
2425
2426 /*
2427 * To keep things simple, assume that we can use the same PIN parameters for the new PIN as
2428 * for the old one, ignoring the ones specified by the caller, with the exception of the
2429 * PIN prompt and the PIN data itself. Note that the old PIN is re-verified since the
2430 * IAS-ECC specification has no implicit verification for the PIN change command. This also
2431 * forces us to always use PIN-pad for the second PIN if the first one was input on a
2432 * PIN-pad.
2433 */
2434 pin_cmd.cmd = SC_PIN_CMD_CHANGE;
2435 pin_cmd.pin2 = pin_cmd.pin1;
2436 pin_cmd.pin2.prompt = data->pin2.prompt;
2437 if (pin_cmd.flags & SC_PIN_CMD_USE_PINPAD) {
2438 pin_cmd.pin2.data = NULL;
2439 pin_cmd.pin2.len = 0;
2440 } else {
2441 pin_cmd.pin2.data = data->pin2.data;
2442 pin_cmd.pin2.len = data->pin2.len;
2443 }
2444
2445 rv = iasecc_check_update_pin(&pin_cmd, &pin_cmd.pin2);
2446 LOG_TEST_RET(ctx, rv, "Invalid PIN2");
2447
2448 rv = iso_ops->pin_cmd(card, &pin_cmd, tries_left);
2449 LOG_FUNC_RETURN(ctx, rv);
2450 }
2451
2452
2453 /*
2454 * The PIN unblock function can handle different PIN-pad input combinations for the PUK and the new
2455 * PIN:
2456 * PUK: NEW PIN: DESCRIPTION:
2457 * Available Available No input.
2458 * Available Absent Only new PIN is input.
2459 * Absent Available Only PUK is input.
2460 * Absent Absent Both PUK and new PIN are input.
2461 */
2462 static int
iasecc_pin_reset(struct sc_card * card,struct sc_pin_cmd_data * data,int * tries_left)2463 iasecc_pin_reset(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2464 {
2465 struct sc_context *ctx = card->ctx;
2466 unsigned char scb;
2467 struct sc_pin_cmd_data pin_cmd;
2468 struct iasecc_pin_policy policy;
2469 int rv;
2470
2471 LOG_FUNC_CALLED(ctx);
2472 sc_log(ctx, "Reset PIN(ref:%i,lengths:%i/%i)", data->pin_reference, data->pin1.len, data->pin2.len);
2473
2474 if (data->pin_type != SC_AC_CHV)
2475 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unblock procedure can be used only with the PINs of type CHV");
2476
2477 rv = iasecc_pin_get_policy(card, data, &policy);
2478 LOG_TEST_RET(ctx, rv, "Failed to get PIN policy");
2479
2480 scb = policy.scbs[IASECC_ACLS_CHV_RESET];
2481 do {
2482 unsigned need_all = scb & IASECC_SCB_METHOD_NEED_ALL ? 1 : 0;
2483 unsigned char se_num = scb & IASECC_SCB_METHOD_MASK_REF;
2484
2485 if (scb & IASECC_SCB_METHOD_USER_AUTH) {
2486 pin_cmd = *data;
2487 if (pin_cmd.puk_reference) {
2488 sc_log(ctx, "Verify PIN with CHV %X", pin_cmd.puk_reference);
2489 pin_cmd.pin_type = SC_AC_CHV;
2490 pin_cmd.pin_reference = pin_cmd.puk_reference;
2491 } else {
2492 sc_log(ctx, "Verify PIN in SE %X", se_num);
2493 pin_cmd.pin_type = SC_AC_SEN;
2494 pin_cmd.pin_reference = se_num;
2495 }
2496 rv = iasecc_pin_verify(card, &pin_cmd, tries_left);
2497 LOG_TEST_RET(ctx, rv, "iasecc_pin_reset() verify PUK error");
2498
2499 if (!need_all)
2500 break;
2501 }
2502
2503 if (scb & IASECC_SCB_METHOD_SM) {
2504 rv = iasecc_sm_pin_reset(card, se_num, data);
2505 LOG_FUNC_RETURN(ctx, rv);
2506 }
2507
2508 if (scb & IASECC_SCB_METHOD_EXT_AUTH) {
2509 rv = iasecc_sm_external_authentication(card, data->pin_reference, tries_left);
2510 LOG_TEST_RET(ctx, rv, "iasecc_pin_reset() external authentication error");
2511 }
2512 } while(0);
2513
2514 /* Use iso 7816 layer for unblock, with implicit pin for PIN1 and the new PIN for PIN2 */
2515 pin_cmd = *data;
2516 pin_cmd.cmd = SC_PIN_CMD_UNBLOCK;
2517 pin_cmd.flags |= SC_PIN_CMD_IMPLICIT_CHANGE;
2518 pin_cmd.pin1.len = 0;
2519
2520 rv = iasecc_pin_merge_policy(card, &pin_cmd, &pin_cmd.pin2, &policy);
2521 LOG_TEST_RET(ctx, rv, "Failed to update PIN2 info");
2522
2523 rv = iso_ops->pin_cmd(card, &pin_cmd, tries_left);
2524
2525 LOG_FUNC_RETURN(ctx, rv);
2526 }
2527
2528
2529 static int
iasecc_pin_cmd(struct sc_card * card,struct sc_pin_cmd_data * data,int * tries_left)2530 iasecc_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left)
2531 {
2532 struct sc_context *ctx = card->ctx;
2533 int rv;
2534
2535 LOG_FUNC_CALLED(ctx);
2536 sc_log(ctx, "iasecc_pin_cmd() cmd 0x%X, PIN type 0x%X, PIN reference %i, PIN-1 %p:%i, PIN-2 %p:%i",
2537 data->cmd, data->pin_type, data->pin_reference,
2538 data->pin1.data, data->pin1.len, data->pin2.data, data->pin2.len);
2539
2540 switch (data->cmd) {
2541 case SC_PIN_CMD_VERIFY:
2542 rv = iasecc_pin_verify(card, data, tries_left);
2543 break;
2544 case SC_PIN_CMD_CHANGE:
2545 if (data->pin_type == SC_AC_AUT)
2546 rv = iasecc_keyset_change(card, data, tries_left);
2547 else
2548 rv = iasecc_pin_change(card, data, tries_left);
2549 break;
2550 case SC_PIN_CMD_UNBLOCK:
2551 rv = iasecc_pin_reset(card, data, tries_left);
2552 break;
2553 case SC_PIN_CMD_GET_INFO:
2554 rv = iasecc_pin_get_info(card, data, tries_left);
2555 break;
2556 default:
2557 sc_log(ctx, "Other pin commands not supported yet: 0x%X", data->cmd);
2558 rv = SC_ERROR_NOT_SUPPORTED;
2559 }
2560
2561 LOG_FUNC_RETURN(ctx, rv);
2562 }
2563
2564
2565 static int
iasecc_get_serialnr(struct sc_card * card,struct sc_serial_number * serial)2566 iasecc_get_serialnr(struct sc_card *card, struct sc_serial_number *serial)
2567 {
2568 struct sc_context *ctx = card->ctx;
2569 struct sc_iin *iin = &card->serialnr.iin;
2570 struct sc_apdu apdu;
2571 unsigned char rbuf[0xC0];
2572 size_t ii, offs, len;
2573 int rv;
2574
2575 LOG_FUNC_CALLED(ctx);
2576 if (card->serialnr.len)
2577 goto end;
2578
2579 memset(&card->serialnr, 0, sizeof(card->serialnr));
2580
2581 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB0, 0x80 | IASECC_SFI_EF_SN, 0);
2582 apdu.le = sizeof(rbuf);
2583 apdu.resp = rbuf;
2584 apdu.resplen = sizeof(rbuf);
2585
2586 rv = sc_transmit_apdu(card, &apdu);
2587 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2588 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2589 LOG_TEST_RET(ctx, rv, "Get 'serial number' data failed");
2590
2591 if (apdu.resplen < 2 || rbuf[0] != ISO7812_PAN_SN_TAG || rbuf[1] > (apdu.resplen-2))
2592 LOG_TEST_RET(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "serial number parse error");
2593 len = rbuf[1];
2594
2595 iin->mii = (rbuf[2] >> 4) & 0x0F;
2596
2597 iin->country = 0;
2598 for (ii=5; ii<8; ii++) {
2599 iin->country *= 10;
2600 iin->country += (rbuf[ii/2] >> ((ii & 0x01) ? 0 : 4)) & 0x0F;
2601 }
2602
2603 iin->issuer_id = 0;
2604 for (ii=8; ii<10; ii++) {
2605 iin->issuer_id *= 10;
2606 iin->issuer_id += (rbuf[ii/2] >> (ii & 0x01 ? 0 : 4)) & 0x0F;
2607 }
2608
2609 /* Copy the serial number from the last 8 bytes (at most) */
2610 offs = len > 8 ? len - 8 : 0;
2611 if (card->type == SC_CARD_TYPE_IASECC_SAGEM) {
2612 /* 5A 0A 92 50 00 20 10 10 25 00 01 3F */
2613 /* 00 02 01 01 02 50 00 13 */
2614 for (ii=0; ii < len - offs; ii++)
2615 *(card->serialnr.value + ii) = ((rbuf[ii + offs + 1] & 0x0F) << 4)
2616 + ((rbuf[ii + offs + 2] & 0xF0) >> 4) ;
2617 card->serialnr.len = ii;
2618 }
2619 else {
2620 for (ii=0; ii < len - offs; ii++)
2621 *(card->serialnr.value + ii) = rbuf[ii + offs + 2];
2622 card->serialnr.len = ii;
2623 }
2624
2625 do {
2626 char txt[0x200];
2627
2628 for (ii=0;ii<card->serialnr.len;ii++)
2629 sprintf(txt + ii*2, "%02X", *(card->serialnr.value + ii));
2630
2631 sc_log(ctx, "serial number '%s'; mii %i; country %i; issuer_id %li", txt, iin->mii, iin->country, iin->issuer_id);
2632 } while(0);
2633
2634 end:
2635 if (serial)
2636 memcpy(serial, &card->serialnr, sizeof(*serial));
2637
2638 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2639 }
2640
2641
2642 static int
iasecc_sdo_create(struct sc_card * card,struct iasecc_sdo * sdo)2643 iasecc_sdo_create(struct sc_card *card, struct iasecc_sdo *sdo)
2644 {
2645 struct sc_context *ctx = card->ctx;
2646 struct sc_apdu apdu;
2647 unsigned char *data = NULL, sdo_class = sdo->sdo_class;
2648 struct iasecc_sdo_update update;
2649 struct iasecc_extended_tlv *field = NULL;
2650 int rv = SC_ERROR_NOT_SUPPORTED, data_len;
2651
2652 LOG_FUNC_CALLED(ctx);
2653 if (sdo->magic != SC_CARDCTL_IASECC_SDO_MAGIC)
2654 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SDO data");
2655
2656 sc_log(ctx, "iasecc_sdo_create(card:%p) %02X%02X%02X", card,
2657 IASECC_SDO_TAG_HEADER, sdo->sdo_class | 0x80, sdo->sdo_ref);
2658
2659 data_len = iasecc_sdo_encode_create(ctx, sdo, &data);
2660 LOG_TEST_RET(ctx, data_len, "iasecc_sdo_create() cannot encode SDO create data");
2661 sc_log(ctx, "iasecc_sdo_create() create data(%i):%s", data_len, sc_dump_hex(data, data_len));
2662
2663 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDB, 0x3F, 0xFF);
2664 apdu.data = data;
2665 apdu.datalen = data_len;
2666 apdu.lc = data_len;
2667 apdu.flags |= SC_APDU_FLAGS_CHAINING;
2668
2669 rv = sc_transmit_apdu(card, &apdu);
2670 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2671 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2672 LOG_TEST_RET(ctx, rv, "iasecc_sdo_create() SDO put data error");
2673
2674 memset(&update, 0, sizeof(update));
2675 update.magic = SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA;
2676 update.sdo_class = sdo->sdo_class;
2677 update.sdo_ref = sdo->sdo_ref;
2678
2679 if (sdo_class == IASECC_SDO_CLASS_RSA_PRIVATE) {
2680 update.fields[0] = sdo->data.prv_key.compulsory;
2681 update.fields[0].parent_tag = IASECC_SDO_PRVKEY_TAG;
2682 field = &sdo->data.prv_key.compulsory;
2683 }
2684 else if (sdo_class == IASECC_SDO_CLASS_RSA_PUBLIC) {
2685 update.fields[0] = sdo->data.pub_key.compulsory;
2686 update.fields[0].parent_tag = IASECC_SDO_PUBKEY_TAG;
2687 field = &sdo->data.pub_key.compulsory;
2688 }
2689 else if (sdo_class == IASECC_SDO_CLASS_KEYSET) {
2690 update.fields[0] = sdo->data.keyset.compulsory;
2691 update.fields[0].parent_tag = IASECC_SDO_KEYSET_TAG;
2692 field = &sdo->data.keyset.compulsory;
2693 }
2694
2695 if (update.fields[0].value && !update.fields[0].on_card) {
2696 rv = iasecc_sdo_put_data(card, &update);
2697 LOG_TEST_RET(ctx, rv, "failed to update 'Compulsory usage' data");
2698
2699 if (field)
2700 field->on_card = 1;
2701 }
2702
2703 free(data);
2704 LOG_FUNC_RETURN(ctx, rv);
2705 }
2706
2707 /* Oberthur's specific */
2708 static int
iasecc_sdo_delete(struct sc_card * card,struct iasecc_sdo * sdo)2709 iasecc_sdo_delete(struct sc_card *card, struct iasecc_sdo *sdo)
2710 {
2711 struct sc_context *ctx = card->ctx;
2712 struct sc_apdu apdu;
2713 unsigned char data[6] = {
2714 0x70, 0x04, 0xBF, 0xFF, 0xFF, 0x00
2715 };
2716 int rv;
2717
2718 LOG_FUNC_CALLED(ctx);
2719 if (sdo->magic != SC_CARDCTL_IASECC_SDO_MAGIC)
2720 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SDO data");
2721
2722 data[2] = IASECC_SDO_TAG_HEADER;
2723 data[3] = sdo->sdo_class | 0x80;
2724 data[4] = sdo->sdo_ref;
2725 sc_log(ctx, "delete SDO %02X%02X%02X", data[2], data[3], data[4]);
2726
2727 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDB, 0x3F, 0xFF);
2728 apdu.data = data;
2729 apdu.datalen = sizeof(data);
2730 apdu.lc = sizeof(data);
2731 apdu.flags |= SC_APDU_FLAGS_CHAINING;
2732
2733 rv = sc_transmit_apdu(card, &apdu);
2734 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2735 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2736 LOG_TEST_RET(ctx, rv, "delete SDO error");
2737
2738 LOG_FUNC_RETURN(ctx, rv);
2739 }
2740
2741
2742 static int
iasecc_sdo_put_data(struct sc_card * card,struct iasecc_sdo_update * update)2743 iasecc_sdo_put_data(struct sc_card *card, struct iasecc_sdo_update *update)
2744 {
2745 struct sc_context *ctx = card->ctx;
2746 struct sc_apdu apdu;
2747 int ii, rv;
2748
2749 LOG_FUNC_CALLED(ctx);
2750 if (update->magic != SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA)
2751 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Invalid SDO update data");
2752
2753 for(ii=0; update->fields[ii].tag && ii < IASECC_SDO_TAGS_UPDATE_MAX; ii++) {
2754 unsigned char *encoded = NULL;
2755 int encoded_len;
2756
2757 encoded_len = iasecc_sdo_encode_update_field(ctx, update->sdo_class, update->sdo_ref,
2758 &update->fields[ii], &encoded);
2759 sc_log(ctx, "iasecc_sdo_put_data() encode[%i]; tag %X; encoded_len %i", ii, update->fields[ii].tag, encoded_len);
2760 LOG_TEST_RET(ctx, encoded_len, "Cannot encode update data");
2761
2762 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDB, 0x3F, 0xFF);
2763 apdu.data = encoded;
2764 apdu.datalen = encoded_len;
2765 apdu.lc = encoded_len;
2766 apdu.flags |= SC_APDU_FLAGS_CHAINING;
2767
2768 rv = sc_transmit_apdu(card, &apdu);
2769 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2770 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2771 LOG_TEST_RET(ctx, rv, "SDO put data error");
2772
2773 free(encoded);
2774 }
2775
2776 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2777 }
2778
2779
2780 static int
iasecc_sdo_key_rsa_put_data(struct sc_card * card,struct iasecc_sdo_rsa_update * update)2781 iasecc_sdo_key_rsa_put_data(struct sc_card *card, struct iasecc_sdo_rsa_update *update)
2782 {
2783 struct sc_context *ctx = card->ctx;
2784 unsigned char scb;
2785 int rv;
2786
2787 LOG_FUNC_CALLED(ctx);
2788
2789 if (update->sdo_prv_key) {
2790 sc_log(ctx, "encode private rsa in %p", &update->update_prv);
2791 rv = iasecc_sdo_encode_rsa_update(card->ctx, update->sdo_prv_key, update->p15_rsa, &update->update_prv);
2792 LOG_TEST_RET(ctx, rv, "failed to encode update of RSA private key");
2793 }
2794
2795 if (update->sdo_pub_key) {
2796 sc_log(ctx, "encode public rsa in %p", &update->update_pub);
2797 if (card->type == SC_CARD_TYPE_IASECC_SAGEM) {
2798 if (update->sdo_pub_key->data.pub_key.cha.value) {
2799 free(update->sdo_pub_key->data.pub_key.cha.value);
2800 memset(&update->sdo_pub_key->data.pub_key.cha, 0, sizeof(update->sdo_pub_key->data.pub_key.cha));
2801 }
2802 }
2803 rv = iasecc_sdo_encode_rsa_update(card->ctx, update->sdo_pub_key, update->p15_rsa, &update->update_pub);
2804 LOG_TEST_RET(ctx, rv, "failed to encode update of RSA public key");
2805 }
2806
2807 if (update->sdo_prv_key) {
2808 sc_log(ctx, "reference of the private key to store: %X", update->sdo_prv_key->sdo_ref);
2809
2810 if (update->sdo_prv_key->docp.acls_contact.size == 0)
2811 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "extremely strange ... there are no ACLs");
2812
2813 scb = update->sdo_prv_key->docp.scbs[IASECC_ACLS_RSAKEY_PUT_DATA];
2814 sc_log(ctx, "'UPDATE PRIVATE RSA' scb 0x%X", scb);
2815
2816 do {
2817 unsigned all_conditions = scb & IASECC_SCB_METHOD_NEED_ALL ? 1 : 0;
2818
2819 if ((scb & IASECC_SCB_METHOD_USER_AUTH) && !all_conditions)
2820 break;
2821
2822 if (scb & IASECC_SCB_METHOD_EXT_AUTH)
2823 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Not yet");
2824
2825 if (scb & IASECC_SCB_METHOD_SM) {
2826 #ifdef ENABLE_SM
2827 rv = iasecc_sm_rsa_update(card, scb & IASECC_SCB_METHOD_MASK_REF, update);
2828 LOG_FUNC_RETURN(ctx, rv);
2829 #else
2830 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "built without support of Secure-Messaging");
2831 #endif
2832 }
2833 } while(0);
2834
2835 rv = iasecc_sdo_put_data(card, &update->update_prv);
2836 LOG_TEST_RET(ctx, rv, "failed to update of RSA private key");
2837 }
2838
2839 if (update->sdo_pub_key) {
2840 sc_log(ctx, "reference of the public key to store: %X", update->sdo_pub_key->sdo_ref);
2841
2842 rv = iasecc_sdo_put_data(card, &update->update_pub);
2843 LOG_TEST_RET(ctx, rv, "failed to update of RSA public key");
2844 }
2845
2846 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
2847 }
2848
2849
2850 static int
iasecc_sdo_tag_from_class(unsigned sdo_class)2851 iasecc_sdo_tag_from_class(unsigned sdo_class)
2852 {
2853 switch (sdo_class & ~IASECC_OBJECT_REF_LOCAL) {
2854 case IASECC_SDO_CLASS_CHV:
2855 return IASECC_SDO_CHV_TAG;
2856 case IASECC_SDO_CLASS_RSA_PRIVATE:
2857 return IASECC_SDO_PRVKEY_TAG;
2858 case IASECC_SDO_CLASS_RSA_PUBLIC:
2859 return IASECC_SDO_PUBKEY_TAG;
2860 case IASECC_SDO_CLASS_SE:
2861 return IASECC_SDO_CLASS_SE;
2862 case IASECC_SDO_CLASS_KEYSET:
2863 return IASECC_SDO_KEYSET_TAG;
2864 }
2865
2866 return -1;
2867 }
2868
2869
2870 static int
iasecc_sdo_get_tagged_data(struct sc_card * card,int sdo_tag,struct iasecc_sdo * sdo)2871 iasecc_sdo_get_tagged_data(struct sc_card *card, int sdo_tag, struct iasecc_sdo *sdo)
2872 {
2873 struct sc_context *ctx = card->ctx;
2874 struct sc_apdu apdu;
2875 unsigned char sbuf[0x100];
2876 size_t offs = sizeof(sbuf) - 1;
2877 unsigned char rbuf[0x400];
2878 int rv;
2879
2880 LOG_FUNC_CALLED(ctx);
2881
2882 sc_log(ctx, "sdo_tag=0x%x sdo_ref=0x%x sdo_class=0x%x", sdo_tag,
2883 sdo->sdo_ref, sdo->sdo_class);
2884
2885 /* XXX: for the CPx, the SDO are available from some specific path */
2886 if (iasecc_is_cpx(card)) {
2887 struct sc_path path;
2888 char *path_str = NULL;
2889 switch(sdo_tag) {
2890 case IASECC_SDO_PRVKEY_TAG:
2891 /* APDU 00 CB 3F FF 0B 4D 09 70 07 BF 90 02 03 7F 48 80 */
2892 path_str = "3F00:0001";
2893 break;
2894 case IASECC_SDO_CHV_TAG:
2895 /* APDU 00 CB 3F FF 0B 4D 09 70 07 BF 81 01 03 7F 41 80 */
2896 path_str = "3F00";
2897 break;
2898 default:
2899 path_str = NULL;
2900 break;
2901 }
2902 if (path_str) {
2903 sc_log(ctx, "Warning: Enforce the path=%s", path_str);
2904 sc_format_path(path_str, &path);
2905 rv = iasecc_select_file(card, &path, NULL);
2906 LOG_TEST_RET(ctx, rv, "path error");
2907 }
2908 }
2909
2910 sbuf[offs--] = 0x80;
2911 sbuf[offs--] = sdo_tag & 0xFF;
2912 if ((sdo_tag >> 8) & 0xFF)
2913 sbuf[offs--] = (sdo_tag >> 8) & 0xFF;
2914 sbuf[offs] = sizeof(sbuf) - offs - 1;
2915 offs--;
2916
2917 sbuf[offs--] = sdo->sdo_ref & 0x9F;
2918 sbuf[offs--] = sdo->sdo_class | IASECC_OBJECT_REF_LOCAL;
2919 sbuf[offs--] = IASECC_SDO_TAG_HEADER;
2920
2921 sbuf[offs] = sizeof(sbuf) - offs - 1;
2922 offs--;
2923 sbuf[offs--] = IASECC_SDO_TEMPLATE_TAG;
2924
2925 sbuf[offs] = sizeof(sbuf) - offs - 1;
2926 offs--;
2927 sbuf[offs] = 0x4D;
2928
2929 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xCB, 0x3F, 0xFF);
2930 apdu.data = sbuf + offs;
2931 apdu.datalen = sizeof(sbuf) - offs;
2932 apdu.lc = sizeof(sbuf) - offs;
2933 apdu.resp = rbuf;
2934 apdu.resplen = sizeof(rbuf);
2935 apdu.le = 0x100;
2936
2937 rv = sc_transmit_apdu(card, &apdu);
2938 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
2939 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
2940 LOG_TEST_RET(ctx, rv, "SDO get data error");
2941
2942 rv = iasecc_sdo_parse(card, apdu.resp, apdu.resplen, sdo);
2943 LOG_TEST_RET(ctx, rv, "cannot parse SDO data");
2944
2945 LOG_FUNC_RETURN(ctx, rv);
2946 }
2947
2948
2949 static int
iasecc_sdo_get_data(struct sc_card * card,struct iasecc_sdo * sdo)2950 iasecc_sdo_get_data(struct sc_card *card, struct iasecc_sdo *sdo)
2951 {
2952 struct sc_context *ctx = card->ctx;
2953 int rv, sdo_tag;
2954
2955 LOG_FUNC_CALLED(ctx);
2956
2957 sdo_tag = iasecc_sdo_tag_from_class(sdo->sdo_class);
2958
2959 rv = iasecc_sdo_get_tagged_data(card, sdo_tag, sdo);
2960 /* When there is no public data 'GET DATA' returns error */
2961 if (rv != SC_ERROR_INCORRECT_PARAMETERS)
2962 LOG_TEST_RET(ctx, rv, "cannot parse ECC SDO data");
2963
2964 rv = iasecc_sdo_get_tagged_data(card, IASECC_DOCP_TAG, sdo);
2965 LOG_TEST_RET(ctx, rv, "cannot parse ECC DOCP data");
2966
2967 LOG_FUNC_RETURN(ctx, rv);
2968 }
2969
2970
2971 static int
iasecc_sdo_generate(struct sc_card * card,struct iasecc_sdo * sdo)2972 iasecc_sdo_generate(struct sc_card *card, struct iasecc_sdo *sdo)
2973 {
2974 struct sc_context *ctx = card->ctx;
2975 struct iasecc_sdo_update update_pubkey;
2976 struct sc_apdu apdu;
2977 unsigned char scb, sbuf[5], rbuf[0x400], exponent[3] = {0x01, 0x00, 0x01};
2978 int offs = 0, rv = SC_ERROR_NOT_SUPPORTED;
2979
2980 LOG_FUNC_CALLED(ctx);
2981
2982 if (sdo->sdo_class != IASECC_SDO_CLASS_RSA_PRIVATE)
2983 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "For a moment, only RSA_PRIVATE class can be accepted for the SDO generation");
2984
2985 if (sdo->docp.acls_contact.size == 0)
2986 LOG_TEST_RET(ctx, SC_ERROR_INVALID_DATA, "Bewildered ... there are no ACLs");
2987
2988 scb = sdo->docp.scbs[IASECC_ACLS_RSAKEY_GENERATE];
2989 sc_log(ctx, "'generate RSA key' SCB 0x%X", scb);
2990 do {
2991 unsigned all_conditions = scb & IASECC_SCB_METHOD_NEED_ALL ? 1 : 0;
2992
2993 if (scb & IASECC_SCB_METHOD_USER_AUTH)
2994 if (!all_conditions)
2995 break;
2996
2997 if (scb & IASECC_SCB_METHOD_EXT_AUTH)
2998 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Not yet");
2999
3000 if (scb & IASECC_SCB_METHOD_SM) {
3001 rv = iasecc_sm_rsa_generate(card, scb & IASECC_SCB_METHOD_MASK_REF, sdo);
3002 LOG_FUNC_RETURN(ctx, rv);
3003 }
3004 } while(0);
3005
3006 memset(&update_pubkey, 0, sizeof(update_pubkey));
3007 update_pubkey.magic = SC_CARDCTL_IASECC_SDO_MAGIC_PUT_DATA;
3008 update_pubkey.sdo_class = IASECC_SDO_CLASS_RSA_PUBLIC;
3009 update_pubkey.sdo_ref = sdo->sdo_ref;
3010
3011 update_pubkey.fields[0].parent_tag = IASECC_SDO_PUBKEY_TAG;
3012 update_pubkey.fields[0].tag = IASECC_SDO_PUBKEY_TAG_E;
3013 update_pubkey.fields[0].value = exponent;
3014 update_pubkey.fields[0].size = sizeof(exponent);
3015
3016 rv = iasecc_sdo_put_data(card, &update_pubkey);
3017 LOG_TEST_RET(ctx, rv, "iasecc_sdo_generate() update SDO public key failed");
3018
3019 offs = 0;
3020 sbuf[offs++] = IASECC_SDO_TEMPLATE_TAG;
3021 sbuf[offs++] = 0x03;
3022 sbuf[offs++] = IASECC_SDO_TAG_HEADER;
3023 sbuf[offs++] = IASECC_SDO_CLASS_RSA_PRIVATE | IASECC_OBJECT_REF_LOCAL;
3024 sbuf[offs++] = sdo->sdo_ref & ~IASECC_OBJECT_REF_LOCAL;
3025
3026 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x47, 0x00, 0x00);
3027 apdu.data = sbuf;
3028 apdu.datalen = offs;
3029 apdu.lc = offs;
3030 apdu.resp = rbuf;
3031 apdu.resplen = sizeof(rbuf);
3032 apdu.le = 0x100;
3033
3034 rv = sc_transmit_apdu(card, &apdu);
3035 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3036 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3037 LOG_TEST_RET(ctx, rv, "SDO get data error");
3038
3039 LOG_FUNC_RETURN(ctx, rv);
3040 }
3041
3042
3043 static int
iasecc_get_chv_reference_from_se(struct sc_card * card,int * se_reference)3044 iasecc_get_chv_reference_from_se(struct sc_card *card, int *se_reference)
3045 {
3046 struct sc_context *ctx = card->ctx;
3047 struct iasecc_se_info se;
3048 struct sc_crt crt;
3049 int rv;
3050
3051 LOG_FUNC_CALLED(ctx);
3052
3053 if (!se_reference)
3054 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid arguments");
3055
3056 memset(&se, 0, sizeof(se));
3057 se.reference = *se_reference;
3058
3059 rv = iasecc_se_get_info(card, &se);
3060 LOG_TEST_RET(ctx, rv, "get SE info error");
3061
3062 memset(&crt, 0, sizeof(crt));
3063 crt.tag = IASECC_CRT_TAG_AT;
3064 crt.usage = IASECC_UQB_AT_USER_PASSWORD;
3065
3066 rv = iasecc_se_get_crt(card, &se, &crt);
3067 LOG_TEST_RET(ctx, rv, "Cannot get 'USER PASSWORD' authentication template");
3068
3069 sc_file_free(se.df);
3070 LOG_FUNC_RETURN(ctx, crt.refs[0]);
3071 }
3072
3073
3074 static int
iasecc_card_ctl(struct sc_card * card,unsigned long cmd,void * ptr)3075 iasecc_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
3076 {
3077 struct sc_context *ctx = card->ctx;
3078 struct iasecc_sdo *sdo = (struct iasecc_sdo *) ptr;
3079
3080 switch (cmd) {
3081 case SC_CARDCTL_GET_SERIALNR:
3082 return iasecc_get_serialnr(card, (struct sc_serial_number *)ptr);
3083 case SC_CARDCTL_IASECC_SDO_CREATE:
3084 sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_CREATE: sdo_class %X", sdo->sdo_class);
3085 return iasecc_sdo_create(card, (struct iasecc_sdo *) ptr);
3086 case SC_CARDCTL_IASECC_SDO_DELETE:
3087 sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_DELETE: sdo_class %X", sdo->sdo_class);
3088 return iasecc_sdo_delete(card, (struct iasecc_sdo *) ptr);
3089 case SC_CARDCTL_IASECC_SDO_PUT_DATA:
3090 sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_PUT_DATA: sdo_class %X", sdo->sdo_class);
3091 return iasecc_sdo_put_data(card, (struct iasecc_sdo_update *) ptr);
3092 case SC_CARDCTL_IASECC_SDO_KEY_RSA_PUT_DATA:
3093 sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_KEY_RSA_PUT_DATA");
3094 return iasecc_sdo_key_rsa_put_data(card, (struct iasecc_sdo_rsa_update *) ptr);
3095 case SC_CARDCTL_IASECC_SDO_GET_DATA:
3096 sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_GET_DATA: sdo_class %X", sdo->sdo_class);
3097 return iasecc_sdo_get_data(card, (struct iasecc_sdo *) ptr);
3098 case SC_CARDCTL_IASECC_SDO_GENERATE:
3099 sc_log(ctx, "CMD SC_CARDCTL_IASECC_SDO_GET_DATA: sdo_class %X", sdo->sdo_class);
3100 return iasecc_sdo_generate(card, (struct iasecc_sdo *) ptr);
3101 case SC_CARDCTL_GET_SE_INFO:
3102 sc_log(ctx, "CMD SC_CARDCTL_GET_SE_INFO: sdo_class %X", sdo->sdo_class);
3103 return iasecc_se_get_info(card, (struct iasecc_se_info *) ptr);
3104 case SC_CARDCTL_GET_CHV_REFERENCE_IN_SE:
3105 sc_log(ctx, "CMD SC_CARDCTL_GET_CHV_REFERENCE_IN_SE");
3106 return iasecc_get_chv_reference_from_se(card, (int *)ptr);
3107 case SC_CARDCTL_IASECC_GET_FREE_KEY_REFERENCE:
3108 sc_log(ctx, "CMD SC_CARDCTL_IASECC_GET_FREE_KEY_REFERENCE");
3109 return iasecc_get_free_reference(card, (struct iasecc_ctl_get_free_reference *)ptr);
3110 }
3111 return SC_ERROR_NOT_SUPPORTED;
3112 }
3113
3114
3115 static int
iasecc_decipher(struct sc_card * card,const unsigned char * in,size_t in_len,unsigned char * out,size_t out_len)3116 iasecc_decipher(struct sc_card *card,
3117 const unsigned char *in, size_t in_len,
3118 unsigned char *out, size_t out_len)
3119 {
3120 struct sc_context *ctx = card->ctx;
3121 struct sc_apdu apdu;
3122 unsigned char sbuf[0x200];
3123 unsigned char resp[SC_MAX_APDU_BUFFER_SIZE];
3124 size_t offs;
3125 int rv;
3126
3127 LOG_FUNC_CALLED(ctx);
3128 sc_log(card->ctx,
3129 "crgram_len %"SC_FORMAT_LEN_SIZE_T"u; outlen %"SC_FORMAT_LEN_SIZE_T"u",
3130 in_len, out_len);
3131 if (!out || !out_len || in_len > SC_MAX_APDU_BUFFER_SIZE)
3132 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3133
3134 offs = 0;
3135 sbuf[offs++] = 0x81;
3136 memcpy(sbuf + offs, in, in_len);
3137 offs += in_len;
3138
3139 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86);
3140 apdu.flags |= SC_APDU_FLAGS_CHAINING;
3141 apdu.data = sbuf;
3142 apdu.datalen = offs;
3143 apdu.lc = offs;
3144 apdu.resp = resp;
3145 apdu.resplen = sizeof(resp);
3146 apdu.le = 256;
3147
3148 rv = sc_transmit_apdu(card, &apdu);
3149 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3150 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3151 LOG_TEST_RET(ctx, rv, "Card returned error");
3152
3153 if (out_len > apdu.resplen)
3154 out_len = apdu.resplen;
3155
3156 memcpy(out, apdu.resp, out_len);
3157 rv = out_len;
3158
3159 LOG_FUNC_RETURN(ctx, rv);
3160 }
3161
3162
3163 static int
iasecc_qsign_data_sha1(struct sc_context * ctx,const unsigned char * in,size_t in_len,struct iasecc_qsign_data * out)3164 iasecc_qsign_data_sha1(struct sc_context *ctx, const unsigned char *in, size_t in_len,
3165 struct iasecc_qsign_data *out)
3166 {
3167 SHA_CTX sha;
3168 SHA_LONG pre_hash_Nl, *hh[5] = {
3169 &sha.h0, &sha.h1, &sha.h2, &sha.h3, &sha.h4
3170 };
3171 int jj, ii;
3172 int hh_size = sizeof(SHA_LONG), hh_num = SHA_DIGEST_LENGTH / sizeof(SHA_LONG);
3173
3174 LOG_FUNC_CALLED(ctx);
3175
3176 if (!in || !in_len || !out)
3177 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3178
3179 sc_log(ctx,
3180 "sc_pkcs15_get_qsign_data() input data length %"SC_FORMAT_LEN_SIZE_T"u",
3181 in_len);
3182 memset(out, 0, sizeof(struct iasecc_qsign_data));
3183
3184 SHA1_Init(&sha);
3185 SHA1_Update(&sha, in, in_len);
3186
3187 for (jj=0; jj<hh_num; jj++)
3188 for(ii=0; ii<hh_size; ii++)
3189 out->pre_hash[jj*hh_size + ii] = ((*hh[jj] >> 8*(hh_size-1-ii)) & 0xFF);
3190 out->pre_hash_size = SHA_DIGEST_LENGTH;
3191 sc_log(ctx, "Pre SHA1:%s", sc_dump_hex(out->pre_hash, out->pre_hash_size));
3192
3193 pre_hash_Nl = sha.Nl - (sha.Nl % (sizeof(sha.data) * 8));
3194 for (ii=0; ii<hh_size; ii++) {
3195 out->counter[ii] = (sha.Nh >> 8*(hh_size-1-ii)) &0xFF;
3196 out->counter[hh_size+ii] = (pre_hash_Nl >> 8*(hh_size-1-ii)) &0xFF;
3197 }
3198 for (ii=0, out->counter_long=0; ii<(int)sizeof(out->counter); ii++)
3199 out->counter_long = out->counter_long*0x100 + out->counter[ii];
3200 sc_log(ctx, "Pre counter(%li):%s", out->counter_long, sc_dump_hex(out->counter, sizeof(out->counter)));
3201
3202 if (sha.num) {
3203 memcpy(out->last_block, in + in_len - sha.num, sha.num);
3204 out->last_block_size = sha.num;
3205 sc_log(ctx, "Last block(%"SC_FORMAT_LEN_SIZE_T"u):%s",
3206 out->last_block_size,
3207 sc_dump_hex(out->last_block, out->last_block_size));
3208 }
3209
3210 SHA1_Final(out->hash, &sha);
3211 out->hash_size = SHA_DIGEST_LENGTH;
3212 sc_log(ctx, "Expected digest %s\n", sc_dump_hex(out->hash, out->hash_size));
3213
3214 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
3215 }
3216
3217
3218 static int
iasecc_qsign_data_sha256(struct sc_context * ctx,const unsigned char * in,size_t in_len,struct iasecc_qsign_data * out)3219 iasecc_qsign_data_sha256(struct sc_context *ctx, const unsigned char *in, size_t in_len,
3220 struct iasecc_qsign_data *out)
3221 {
3222 SHA256_CTX sha256;
3223 SHA_LONG pre_hash_Nl;
3224 int jj, ii;
3225 int hh_size = sizeof(SHA_LONG), hh_num = SHA256_DIGEST_LENGTH / sizeof(SHA_LONG);
3226
3227 LOG_FUNC_CALLED(ctx);
3228 if (!in || !in_len || !out)
3229 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3230
3231 sc_log(ctx,
3232 "sc_pkcs15_get_qsign_data() input data length %"SC_FORMAT_LEN_SIZE_T"u",
3233 in_len);
3234 memset(out, 0, sizeof(struct iasecc_qsign_data));
3235
3236 SHA256_Init(&sha256);
3237 SHA256_Update(&sha256, in, in_len);
3238
3239 for (jj=0; jj<hh_num; jj++)
3240 for(ii=0; ii<hh_size; ii++)
3241 out->pre_hash[jj*hh_size + ii] = ((sha256.h[jj] >> 8*(hh_size-1-ii)) & 0xFF);
3242 out->pre_hash_size = SHA256_DIGEST_LENGTH;
3243 sc_log(ctx, "Pre hash:%s", sc_dump_hex(out->pre_hash, out->pre_hash_size));
3244
3245 pre_hash_Nl = sha256.Nl - (sha256.Nl % (sizeof(sha256.data) * 8));
3246 for (ii=0; ii<hh_size; ii++) {
3247 out->counter[ii] = (sha256.Nh >> 8*(hh_size-1-ii)) &0xFF;
3248 out->counter[hh_size+ii] = (pre_hash_Nl >> 8*(hh_size-1-ii)) &0xFF;
3249 }
3250 for (ii=0, out->counter_long=0; ii<(int)sizeof(out->counter); ii++)
3251 out->counter_long = out->counter_long*0x100 + out->counter[ii];
3252 sc_log(ctx, "Pre counter(%li):%s", out->counter_long, sc_dump_hex(out->counter, sizeof(out->counter)));
3253
3254 if (sha256.num) {
3255 memcpy(out->last_block, in + in_len - sha256.num, sha256.num);
3256 out->last_block_size = sha256.num;
3257 sc_log(ctx, "Last block(%"SC_FORMAT_LEN_SIZE_T"u):%s",
3258 out->last_block_size,
3259 sc_dump_hex(out->last_block, out->last_block_size));
3260 }
3261
3262 SHA256_Final(out->hash, &sha256);
3263 out->hash_size = SHA256_DIGEST_LENGTH;
3264 sc_log(ctx, "Expected digest %s\n", sc_dump_hex(out->hash, out->hash_size));
3265
3266 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
3267 }
3268
3269
3270 static int
iasecc_compute_signature_dst(struct sc_card * card,const unsigned char * in,size_t in_len,unsigned char * out,size_t out_len)3271 iasecc_compute_signature_dst(struct sc_card *card,
3272 const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len)
3273 {
3274 struct sc_context *ctx = card->ctx;
3275 struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data;
3276 struct sc_security_env *env = &prv->security_env;
3277 struct iasecc_qsign_data qsign_data;
3278 struct sc_apdu apdu;
3279 size_t offs = 0, hash_len = 0;
3280 unsigned char sbuf[SC_MAX_APDU_BUFFER_SIZE];
3281 unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
3282 int rv = SC_SUCCESS;
3283
3284 LOG_FUNC_CALLED(ctx);
3285 sc_log(ctx,
3286 "iasecc_compute_signature_dst() input length %"SC_FORMAT_LEN_SIZE_T"u",
3287 in_len);
3288 if (env->operation != SC_SEC_OPERATION_SIGN)
3289 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "It's not SC_SEC_OPERATION_SIGN");
3290 else if (!(prv->key_size & 0x1E0) || (prv->key_size & ~0x1E0))
3291 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid key size for SC_SEC_OPERATION_SIGN");
3292
3293 memset(&qsign_data, 0, sizeof(qsign_data));
3294 if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) {
3295 rv = iasecc_qsign_data_sha1(card->ctx, in, in_len, &qsign_data);
3296 }
3297 else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA256) {
3298 rv = iasecc_qsign_data_sha256(card->ctx, in, in_len, &qsign_data);
3299 }
3300 else
3301 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Need RSA_HASH_SHA1 or RSA_HASH_SHA256 algorithm");
3302 LOG_TEST_RET(ctx, rv, "Cannot get QSign data");
3303
3304 sc_log(ctx,
3305 "iasecc_compute_signature_dst() hash_len %"SC_FORMAT_LEN_SIZE_T"u; key_size %"SC_FORMAT_LEN_SIZE_T"u",
3306 hash_len, prv->key_size);
3307
3308 memset(sbuf, 0, sizeof(sbuf));
3309 sbuf[offs++] = 0x90;
3310 if (qsign_data.counter_long) {
3311 sbuf[offs++] = qsign_data.hash_size + 8;
3312 memcpy(sbuf + offs, qsign_data.pre_hash, qsign_data.pre_hash_size);
3313 offs += qsign_data.pre_hash_size;
3314 memcpy(sbuf + offs, qsign_data.counter, sizeof(qsign_data.counter));
3315 offs += sizeof(qsign_data.counter);
3316 }
3317 else {
3318 sbuf[offs++] = 0;
3319 }
3320
3321 sbuf[offs++] = 0x80;
3322 sbuf[offs++] = qsign_data.last_block_size;
3323 memcpy(sbuf + offs, qsign_data.last_block, qsign_data.last_block_size);
3324 offs += qsign_data.last_block_size;
3325
3326 sc_log(ctx,
3327 "iasecc_compute_signature_dst() offs %"SC_FORMAT_LEN_SIZE_T"u; OP(meth:%X,ref:%X)",
3328 offs, prv->op_method, prv->op_ref);
3329 if (prv->op_method == SC_AC_SCB && (prv->op_ref & IASECC_SCB_METHOD_SM))
3330 LOG_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Not yet");
3331
3332 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x90, 0xA0);
3333 apdu.data = sbuf;
3334 apdu.datalen = offs;
3335 apdu.lc = offs;
3336
3337 rv = sc_transmit_apdu(card, &apdu);
3338 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3339 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3340 LOG_TEST_RET(ctx, rv, "Compute signature failed");
3341
3342 sc_log(ctx, "iasecc_compute_signature_dst() partial hash OK");
3343
3344 sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x9E, 0x9A);
3345 apdu.resp = rbuf;
3346 apdu.resplen = prv->key_size;
3347 apdu.le = prv->key_size;
3348
3349 rv = sc_transmit_apdu(card, &apdu);
3350 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3351 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3352 LOG_TEST_RET(ctx, rv, "Compute signature failed");
3353
3354 sc_log(ctx,
3355 "iasecc_compute_signature_dst() DST resplen %"SC_FORMAT_LEN_SIZE_T"u",
3356 apdu.resplen);
3357 if (apdu.resplen > out_len)
3358 LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Result buffer too small for the DST signature");
3359
3360 memcpy(out, apdu.resp, apdu.resplen);
3361
3362 LOG_FUNC_RETURN(ctx, apdu.resplen);
3363 }
3364
3365
3366 static int
iasecc_compute_signature_at(struct sc_card * card,const unsigned char * in,size_t in_len,unsigned char * out,size_t out_len)3367 iasecc_compute_signature_at(struct sc_card *card,
3368 const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len)
3369 {
3370 struct sc_context *ctx = card->ctx;
3371 struct iasecc_private_data *prv = (struct iasecc_private_data *) card->drv_data;
3372 struct sc_security_env *env = &prv->security_env;
3373 struct sc_apdu apdu;
3374 size_t offs = 0, sz = 0;
3375 unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE];
3376 int rv;
3377
3378 LOG_FUNC_CALLED(ctx);
3379 if (env->operation != SC_SEC_OPERATION_AUTHENTICATE)
3380 LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "It's not SC_SEC_OPERATION_AUTHENTICATE");
3381
3382 sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, 0x00);
3383 apdu.datalen = in_len;
3384 apdu.data = in;
3385 apdu.lc = in_len;
3386 apdu.resp = rbuf;
3387 apdu.resplen = sizeof(rbuf);
3388 apdu.le = 0x100;
3389
3390 rv = sc_transmit_apdu(card, &apdu);
3391 LOG_TEST_RET(ctx, rv, "APDU transmit failed");
3392 rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
3393 LOG_TEST_RET(ctx, rv, "Compute signature failed");
3394
3395 do {
3396 if (offs + apdu.resplen > out_len)
3397 LOG_TEST_RET(ctx, SC_ERROR_BUFFER_TOO_SMALL, "Buffer too small to return signature");
3398
3399 memcpy(out + offs, rbuf, apdu.resplen);
3400 offs += apdu.resplen;
3401
3402 if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
3403 break;
3404
3405 if (apdu.sw1 == 0x61) {
3406 sz = apdu.sw2 == 0x00 ? 0x100 : apdu.sw2;
3407 rv = iso_ops->get_response(card, &sz, rbuf);
3408 LOG_TEST_RET(ctx, rv, "Get response error");
3409
3410 apdu.resplen = rv;
3411 }
3412 else {
3413 LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "Impossible error: SW1 is not 0x90 neither 0x61");
3414 }
3415
3416 } while(rv > 0);
3417
3418 LOG_FUNC_RETURN(ctx, offs);
3419 }
3420
3421
3422 static int
iasecc_compute_signature(struct sc_card * card,const unsigned char * in,size_t in_len,unsigned char * out,size_t out_len)3423 iasecc_compute_signature(struct sc_card *card,
3424 const unsigned char *in, size_t in_len, unsigned char *out, size_t out_len)
3425 {
3426 struct sc_context *ctx;
3427 struct iasecc_private_data *prv;
3428 struct sc_security_env *env;
3429
3430 if (!card || !in || !out)
3431 return SC_ERROR_INVALID_ARGUMENTS;
3432
3433 ctx = card->ctx;
3434 prv = (struct iasecc_private_data *) card->drv_data;
3435 env = &prv->security_env;
3436
3437 LOG_FUNC_CALLED(ctx);
3438 sc_log(ctx,
3439 "inlen %"SC_FORMAT_LEN_SIZE_T"u, outlen %"SC_FORMAT_LEN_SIZE_T"u",
3440 in_len, out_len);
3441
3442 if (env->operation == SC_SEC_OPERATION_SIGN)
3443 return iasecc_compute_signature_dst(card, in, in_len, out, out_len);
3444 else if (env->operation == SC_SEC_OPERATION_AUTHENTICATE)
3445 return iasecc_compute_signature_at(card, in, in_len, out, out_len);
3446
3447 LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3448 }
3449
3450
3451 static int
iasecc_read_public_key(struct sc_card * card,unsigned type,struct sc_path * key_path,unsigned ref,unsigned size,unsigned char ** out,size_t * out_len)3452 iasecc_read_public_key(struct sc_card *card, unsigned type,
3453 struct sc_path *key_path, unsigned ref, unsigned size,
3454 unsigned char **out, size_t *out_len)
3455 {
3456 struct sc_context *ctx = card->ctx;
3457 struct iasecc_sdo sdo;
3458 struct sc_pkcs15_bignum bn[2];
3459 struct sc_pkcs15_pubkey_rsa rsa_key;
3460 int rv;
3461
3462 LOG_FUNC_CALLED(ctx);
3463 if (type != SC_ALGORITHM_RSA)
3464 LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
3465
3466 sc_log(ctx, "read public kay(ref:%i;size:%i)", ref, size);
3467
3468 memset(&bn, 0, sizeof bn);
3469 memset(&sdo, 0, sizeof(sdo));
3470 sdo.sdo_class = IASECC_SDO_CLASS_RSA_PUBLIC;
3471 sdo.sdo_ref = ref & ~IASECC_OBJECT_REF_LOCAL;
3472
3473 rv = iasecc_sdo_get_data(card, &sdo);
3474 LOG_TEST_GOTO_ERR(ctx, rv, "failed to read public key: cannot get RSA SDO data");
3475
3476 if (out)
3477 *out = NULL;
3478 if (out_len)
3479 *out_len = 0;
3480
3481 bn[0].data = (unsigned char *) malloc(sdo.data.pub_key.n.size);
3482 if (!bn[0].data)
3483 LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "failed to read public key: cannot allocate modulus");
3484 bn[0].len = sdo.data.pub_key.n.size;
3485 memcpy(bn[0].data, sdo.data.pub_key.n.value, sdo.data.pub_key.n.size);
3486
3487 bn[1].data = (unsigned char *) malloc(sdo.data.pub_key.e.size);
3488 if (!bn[1].data)
3489 LOG_TEST_GOTO_ERR(ctx, SC_ERROR_OUT_OF_MEMORY, "failed to read public key: cannot allocate exponent");
3490 bn[1].len = sdo.data.pub_key.e.size;
3491 memcpy(bn[1].data, sdo.data.pub_key.e.value, sdo.data.pub_key.e.size);
3492
3493 rsa_key.modulus = bn[0];
3494 rsa_key.exponent = bn[1];
3495
3496 rv = sc_pkcs15_encode_pubkey_rsa(ctx, &rsa_key, out, out_len);
3497 LOG_TEST_GOTO_ERR(ctx, rv, "failed to read public key: cannot encode RSA public key");
3498
3499 if (out && out_len)
3500 sc_log(ctx, "encoded public key: %s", sc_dump_hex(*out, *out_len));
3501
3502 err:
3503 if (bn[0].data)
3504 free(bn[0].data);
3505 if (bn[1].data)
3506 free(bn[1].data);
3507
3508 iasecc_sdo_free_fields(card, &sdo);
3509
3510 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
3511 }
3512
3513
3514 static int
iasecc_get_free_reference(struct sc_card * card,struct iasecc_ctl_get_free_reference * ctl_data)3515 iasecc_get_free_reference(struct sc_card *card, struct iasecc_ctl_get_free_reference *ctl_data)
3516 {
3517 struct sc_context *ctx = card->ctx;
3518 struct iasecc_sdo *sdo = NULL;
3519 int idx, rv;
3520
3521 LOG_FUNC_CALLED(ctx);
3522
3523 if ((ctl_data->key_size % 0x40) || ctl_data->index < 1 || (ctl_data->index > IASECC_OBJECT_REF_MAX))
3524 LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
3525
3526 sc_log(ctx, "get reference for key(index:%i,usage:%X,access:%X)", ctl_data->index, ctl_data->usage, ctl_data->access);
3527 /* TODO: when looking for the slot for the signature keys, check also PSO_SIGNATURE ACL */
3528 for (idx = ctl_data->index; idx <= IASECC_OBJECT_REF_MAX; idx++) {
3529 unsigned char sdo_tag[3] = {
3530 IASECC_SDO_TAG_HEADER, IASECC_OBJECT_REF_LOCAL | IASECC_SDO_CLASS_RSA_PRIVATE, idx
3531 };
3532 size_t sz;
3533
3534 if (sdo)
3535 iasecc_sdo_free(card, sdo);
3536
3537 rv = iasecc_sdo_allocate_and_parse(card, sdo_tag, 3, &sdo);
3538 LOG_TEST_RET(ctx, rv, "cannot parse SDO data");
3539
3540 rv = iasecc_sdo_get_data(card, sdo);
3541 if (rv == SC_ERROR_DATA_OBJECT_NOT_FOUND) {
3542 iasecc_sdo_free(card, sdo);
3543
3544 sc_log(ctx, "found empty key slot %i", idx);
3545 break;
3546 } else if (rv != SC_SUCCESS) {
3547 iasecc_sdo_free(card, sdo);
3548
3549 sc_log(ctx, "get new key reference failed");
3550 LOG_FUNC_RETURN(ctx, rv);
3551 }
3552
3553 sz = *(sdo->docp.size.value + 0) * 0x100 + *(sdo->docp.size.value + 1);
3554 sc_log(ctx,
3555 "SDO(idx:%i) size %"SC_FORMAT_LEN_SIZE_T"u; key_size %"SC_FORMAT_LEN_SIZE_T"u",
3556 idx, sz, ctl_data->key_size);
3557
3558 if (sz != ctl_data->key_size / 8) {
3559 sc_log(ctx,
3560 "key index %i ignored: different key sizes %"SC_FORMAT_LEN_SIZE_T"u/%"SC_FORMAT_LEN_SIZE_T"u",
3561 idx, sz, ctl_data->key_size / 8);
3562 continue;
3563 }
3564
3565 if (sdo->docp.non_repudiation.value) {
3566 sc_log(ctx, "non repudiation flag %X", sdo->docp.non_repudiation.value[0]);
3567 if ((ctl_data->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) && !(*sdo->docp.non_repudiation.value)) {
3568 sc_log(ctx, "key index %i ignored: need non repudiation", idx);
3569 continue;
3570 }
3571
3572 if (!(ctl_data->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) && *sdo->docp.non_repudiation.value) {
3573 sc_log(ctx, "key index %i ignored: don't need non-repudiation", idx);
3574 continue;
3575 }
3576 }
3577
3578 if (ctl_data->access & SC_PKCS15_PRKEY_ACCESS_LOCAL) {
3579 if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_GENERATE] == IASECC_SCB_NEVER) {
3580 sc_log(ctx, "key index %i ignored: GENERATE KEY not allowed", idx);
3581 continue;
3582 }
3583 }
3584 else {
3585 if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_PUT_DATA] == IASECC_SCB_NEVER) {
3586 sc_log(ctx, "key index %i ignored: PUT DATA not allowed", idx);
3587 continue;
3588 }
3589 }
3590
3591 if ((ctl_data->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) && (ctl_data->usage & SC_PKCS15_PRKEY_USAGE_SIGN)) {
3592 if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_PSO_SIGN] == IASECC_SCB_NEVER) {
3593 sc_log(ctx, "key index %i ignored: PSO SIGN not allowed", idx);
3594 continue;
3595 }
3596 }
3597 else if (ctl_data->usage & SC_PKCS15_PRKEY_USAGE_SIGN) {
3598 if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_INTERNAL_AUTH] == IASECC_SCB_NEVER) {
3599 sc_log(ctx, "key index %i ignored: INTERNAL AUTHENTICATE not allowed", idx);
3600 continue;
3601 }
3602 }
3603
3604 if (ctl_data->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP)) {
3605 if (sdo->docp.scbs[IASECC_ACLS_RSAKEY_PSO_DECIPHER] == IASECC_SCB_NEVER) {
3606 sc_log(ctx, "key index %i ignored: PSO DECIPHER not allowed", idx);
3607 continue;
3608 }
3609 }
3610
3611 break;
3612 }
3613
3614 ctl_data->index = idx;
3615
3616 if (idx > IASECC_OBJECT_REF_MAX)
3617 LOG_FUNC_RETURN(ctx, SC_ERROR_DATA_OBJECT_NOT_FOUND);
3618
3619 LOG_FUNC_RETURN(ctx, SC_SUCCESS);
3620 }
3621
3622
3623 static struct sc_card_driver *
sc_get_driver(void)3624 sc_get_driver(void)
3625 {
3626 struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
3627
3628 if (!iso_ops)
3629 iso_ops = iso_drv->ops;
3630
3631 iasecc_ops = *iso_ops;
3632
3633 iasecc_ops.match_card = iasecc_match_card;
3634 iasecc_ops.init = iasecc_init;
3635 iasecc_ops.finish = iasecc_finish;
3636 iasecc_ops.read_binary = iasecc_read_binary;
3637 /* write_binary: ISO7816 implementation works */
3638 /* update_binary: ISO7816 implementation works */
3639 iasecc_ops.erase_binary = iasecc_erase_binary;
3640 /* resize_binary */
3641 /* read_record: Untested */
3642 /* write_record: Untested */
3643 /* append_record: Untested */
3644 /* update_record: Untested */
3645 iasecc_ops.select_file = iasecc_select_file;
3646 /* get_response: Untested */
3647 iasecc_ops.get_challenge = iasecc_get_challenge;
3648 iasecc_ops.logout = iasecc_logout;
3649 /* restore_security_env */
3650 iasecc_ops.set_security_env = iasecc_set_security_env;
3651 iasecc_ops.decipher = iasecc_decipher;
3652 iasecc_ops.compute_signature = iasecc_compute_signature;
3653 iasecc_ops.create_file = iasecc_create_file;
3654 iasecc_ops.delete_file = iasecc_delete_file;
3655 /* list_files */
3656 iasecc_ops.check_sw = iasecc_check_sw;
3657 iasecc_ops.card_ctl = iasecc_card_ctl;
3658 iasecc_ops.process_fci = iasecc_process_fci;
3659 /* construct_fci: Not needed */
3660 iasecc_ops.pin_cmd = iasecc_pin_cmd;
3661 /* get_data: Not implemented */
3662 /* put_data: Not implemented */
3663 /* delete_record: Not implemented */
3664
3665 iasecc_ops.read_public_key = iasecc_read_public_key;
3666
3667 return &iasecc_drv;
3668 }
3669
3670 struct sc_card_driver *
sc_get_iasecc_driver(void)3671 sc_get_iasecc_driver(void)
3672 {
3673 return sc_get_driver();
3674 }
3675
3676 #else
3677
3678 /* we need to define the functions below to export them */
3679 #include "errors.h"
3680
3681 int
iasecc_se_get_info()3682 iasecc_se_get_info()
3683 {
3684 return SC_ERROR_NOT_SUPPORTED;
3685 }
3686
3687 #endif /* ENABLE_OPENSSL */
3688