Ticket #177: itacns-patch4.diff
| File itacns-patch4.diff, 39.9 KB (added by ep, 18 months ago) |
|---|
-
etc/opensc.conf.in
diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 3d00b1b..c432e21 100644
a b app default { 275 275 # enable_builtin_emulation = no; 276 276 # 277 277 # List of the builtin pkcs15 emulators to test 278 # Default: esteid, openpgp, tcos, starcert, i nfocamere, postecert, actalis, atrust-acos, gemsafeGPK, gemsafeV1, tccardos, PIV-II;278 # Default: esteid, openpgp, tcos, starcert, itacns, infocamere, postecert, actalis, atrust-acos, gemsafeGPK, gemsafeV1, tccardos, PIV-II; 279 279 # builtin_emulators = openpgp; 280 280 281 281 # additional settings per driver -
src/libopensc/Makefile.am
diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 8837952..dfe8ef0 100644
a b libopensc_la_SOURCES = \ 37 37 card-incrypto34.c card-piv.c card-muscle.c card-acos5.c \ 38 38 card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ 39 39 card-rtecp.c card-westcos.c card-myeid.c card-ias.c \ 40 card-javacard.c \40 card-javacard.c card-itacns.c \ 41 41 \ 42 42 pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \ 43 43 pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \ 44 44 pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ 45 45 pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c pkcs15-oberthur.c \ 46 pkcs15-itacns.c \ 46 47 compression.c p15card-helper.c \ 47 48 libopensc.exports 48 49 if WIN32 -
src/libopensc/Makefile.mak
diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index e93ac0c..230ef76 100644
a b OBJECTS = \ 21 21 card-incrypto34.obj card-piv.obj card-muscle.obj card-acos5.obj \ 22 22 card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \ 23 23 card-rtecp.obj card-westcos.obj card-myeid.obj card-ias.obj \ 24 card-javacard.obj \24 card-javacard.obj card-itacns.obj \ 25 25 \ 26 26 pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \ 27 27 pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \ 28 28 pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ 29 29 pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-oberthur.obj \ 30 pkcs15-itacns.obj \ 30 31 compression.obj p15card-helper.obj \ 31 32 $(TOPDIR)\win32\versioninfo.res 32 33 -
src/libopensc/card-cardos.c
diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 555eabe..f6cff9f 100644
a b 30 30 #include "asn1.h" 31 31 #include "cardctl.h" 32 32 33 #define MAX_LE 240 34 33 35 static const struct sc_card_operations *iso_ops = NULL; 34 36 35 37 static struct sc_card_operations cardos_ops; … … cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, 813 815 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); 814 816 if (outlen < datalen) 815 817 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_BUFFER_TOO_SMALL); 816 outlen = datalen; 818 819 if (outlen > MAX_LE) 820 outlen = MAX_LE; 817 821 818 822 /* XXX As we don't know what operations are allowed with a 819 823 * certain key, let's try RSA_PURE etc. and see which operation -
new file src/libopensc/card-itacns.c
diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c new file mode 100644 index 0000000..ff233f3
- + 1 /* 2 * card-itacns.c: Support for Italian CNS 3 * 4 * Copyright (C) 2008 Emanuele Pucciarelli <ep@acm.org> 5 * Copyright (C) 2005 ST Incard srl, Giuseppe Amato <giuseppe dot amato at st dot com>, <midori3@gmail.com> 6 * Copyright (C) 2002 Andreas Jellinghaus <aj@dungeon.inka.de> 7 * Copyright (C) 2001 Juha Yrjölä <juha.yrjola@iki.fi> 8 * 9 * This library is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * This library is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this library; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 */ 23 24 /* 25 * Specifications for the development of this driver come from: 26 * http://www.cnipa.gov.it/html/docs/CNS%20Functional%20Specification%201.1.5_11012010.pdf 27 */ 28 29 #include "internal.h" 30 #include "cardctl.h" 31 #include "itacns.h" 32 #include <ctype.h> 33 #include <string.h> 34 #include <stdlib.h> 35 36 #define ITACNS_MAX_PAYLOAD 0xff 37 38 static const struct sc_card_operations *default_ops = NULL; 39 40 static struct sc_card_operations itacns_ops; 41 static struct sc_card_driver itacns_drv = { 42 "Carta Nazionale dei Servizi", 43 "itacns", 44 &itacns_ops, 45 NULL, 0, NULL 46 }; 47 48 /* 49 * Card matching 50 */ 51 52 53 /* List of ATR's for "hard" matching. */ 54 static struct sc_atr_table itacns_atrs[] = { 55 { "3b:f4:18:00:ff:81:31:80:55:00:31:80:00:c7", NULL, NULL, SC_CARD_TYPE_ITACNS_CIE_V1, 0, NULL}, 56 { NULL, NULL, NULL, 0, 0, NULL} 57 }; 58 59 /* Output debug info */ 60 #define matchdebug(idx, c) do { \ 61 sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Matching %x against atr[%d] == %x", c, idx, atr[idx]); \ 62 } while(0); 63 64 /* Check that we are not looking at values beyond the ATR's length. 65 * If we are, then the card does not match. */ 66 #define itacns_atr_l(idx) do {if (idx >= card->atr_len) return 0;} while(0); 67 68 /* Match byte exactly and increment index. */ 69 #define itacns_atr_match(idx, c) do { \ 70 itacns_atr_l(idx); \ 71 matchdebug(idx, c); \ 72 if (((u8)atr[idx]) != c) return 0; \ 73 idx++; \ 74 } while(0); 75 76 /* Match masked bits and increment index. */ 77 #define itacns_atr_mmatch(idx, c, mask) do { \ 78 itacns_atr_l(idx); \ 79 if ((((u8)atr[idx]) & mask) != c) return 0; \ 80 idx ++; \ 81 } while(0); 82 83 /* Macro to access private driver data. */ 84 #define DRVDATA(card) ((itacns_drv_data_t *) card->drv_data) 85 86 87 int itacns_match_cns_card(sc_card_t *card, int i) 88 { 89 unsigned char *atr = card->atr; 90 sc_context_t *ctx; 91 ctx = card->ctx; 92 93 94 itacns_atr_match(i, 0x01); /* H7 */ 95 i += 2; /* H8, H9 */ 96 itacns_atr_match(i, 'C'); /* H10 */ 97 itacns_atr_match(i, 'N'); /* H11 */ 98 itacns_atr_match(i, 'S'); /* H12 */ 99 100 /* H13 */ 101 /* Version byte: h.l, h in the high nibble, l in the low nibble. */ 102 if(card->driver) { 103 DRVDATA(card)->cns_version = atr[i]; 104 } 105 /* Warn if the version is not 1.0. */ 106 if(atr[i] != 0x10) { 107 char version[8]; 108 snprintf(version, sizeof(version), "%d.%d", (atr[i] >> 4) & 0x0f, atr[i] & 0x0f); 109 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CNS card version %s; no official specifications " 110 "are published. Proceeding anyway.\n", version); 111 } 112 i++; 113 114 itacns_atr_match(i, 0x31); /* H14 */ 115 itacns_atr_match(i, 0x80); /* H15 */ 116 117 card->type = SC_CARD_TYPE_ITACNS_CNS; 118 119 return 1; 120 } 121 122 int itacns_match_cie_card(sc_card_t *card, int i) 123 { 124 unsigned char *atr = card->atr; 125 sc_context_t *ctx; 126 ctx = card->ctx; 127 128 itacns_atr_match(i, 0x02); /* H7 */ 129 itacns_atr_match(i, 'I'); /* H8 */ 130 itacns_atr_match(i, 'T'); /* H9 */ 131 itacns_atr_match(i, 'I'); /* H10 */ 132 itacns_atr_match(i, 'D'); /* H11 */ 133 itacns_atr_match(i, 0x20); /* H12 */ 134 itacns_atr_match(i, 0x20); /* H13 */ 135 itacns_atr_match(i, 0x31); /* H14 */ 136 itacns_atr_match(i, 0x80); /* H15 */ 137 138 card->type = SC_CARD_TYPE_ITACNS_CIE_V2; 139 140 return 1; 141 } 142 143 int itacns_match_card(sc_card_t *card) 144 { 145 int i = 0, r; 146 unsigned char *atr = card->atr; 147 sc_context_t *ctx; 148 ctx = card->ctx; 149 150 /* Try table first */ 151 r = _sc_match_atr(card, itacns_atrs, &card->type); 152 if(r >= 0) return 1; 153 154 /* The ATR was not recognized; try to match it 155 according to the official specs. */ 156 157 /* Check ATR up to byte H6 */ 158 itacns_atr_match(i, 0x3b); /* TS */ 159 itacns_atr_mmatch(i, 0x8f, 0x8f); /* T0 */ 160 /* TA1, TB1, TC1 */ 161 if(atr[1] & 0x40) i++; 162 if(atr[1] & 0x20) i++; 163 if(atr[1] & 0x10) i++; 164 /* TD1 */ 165 int td1_idx = i; 166 itacns_atr_mmatch(i, 0x81, 0x8f); 167 /* TA2, TB2, TC2 */ 168 if(atr[td1_idx] & 0x40) i++; 169 if(atr[td1_idx] & 0x20) i++; 170 if(atr[td1_idx] & 0x10) i++; 171 /* TD2 */ 172 itacns_atr_match(i, 0x31); 173 i += 2; /* TA3, TB3 */ 174 itacns_atr_match(i, 0x00); /* H1 */ 175 itacns_atr_match(i, 0x6b); /* H2 */ 176 /* Store interesting data */ 177 if(card->driver) { 178 DRVDATA(card)->ic_manufacturer_code = card->atr[i]; 179 DRVDATA(card)->mask_manufacturer_code = card->atr[i+1]; 180 DRVDATA(card)->os_version_h = card->atr[i+2]; 181 DRVDATA(card)->os_version_l = card->atr[i+3]; 182 } 183 i += 4; /* H3, H4, H5, H6 */ 184 185 /* Check final part. */ 186 if (itacns_match_cns_card(card, i)) return 1; 187 if (itacns_match_cie_card(card, i)) return 1; 188 189 /* No card type was matched. */ 190 return 0; 191 } 192 193 /* 194 * Initialization and termination 195 */ 196 197 static int itacns_init(sc_card_t *card) 198 { 199 SC_FUNC_CALLED(card->ctx, 1); 200 201 unsigned long flags; 202 203 card->name = "CNS card"; 204 card->cla = 0x00; 205 206 card->drv_data = calloc(1, sizeof(itacns_drv_data_t)); 207 208 /* Match ATR again to find the card data. */ 209 itacns_match_card(card); 210 211 /* Set up algorithm info. */ 212 flags = SC_ALGORITHM_NEED_USAGE 213 | SC_ALGORITHM_RSA_RAW 214 | SC_ALGORITHM_RSA_HASHES 215 ; 216 _sc_card_add_rsa_alg(card, 1024, flags, 0); 217 218 return 0; 219 } 220 221 static int itacns_finish(struct sc_card *card) 222 { 223 if(card->drv_data) { 224 free(card->drv_data); 225 } 226 return 0; 227 } 228 229 230 231 /* 232 * Restore the indicated SE 233 */ 234 static int itacns_restore_security_env(sc_card_t *card, int se_num) 235 { 236 sc_apdu_t apdu; 237 int r; 238 239 SC_FUNC_CALLED(card->ctx, 1); 240 241 /* 242 * The Italian CNS requires a 0-valued Lc byte at the end of the APDU 243 * (see paragraph 13.14 of the Functional Specification), but since 244 * it is invalid, we "cheat" and pretend it's a Le byte. 245 * 246 * For this workaround, we must allocate and supply a response buffer, 247 * even though we know it will not be used (and we do not even check it). 248 */ 249 250 u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; 251 sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x22, 0xF3, se_num); 252 apdu.resp = rbuf; 253 apdu.resplen = sizeof(rbuf); 254 apdu.le = 0; 255 256 r = sc_transmit_apdu(card, &apdu); 257 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 258 259 r = sc_check_sw(card, apdu.sw1, apdu.sw2); 260 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); 261 262 SC_FUNC_RETURN(card->ctx, 1, r); 263 } 264 265 /* 266 * Set the security context 267 * Things get a little messy here. It seems you cannot do any 268 * crypto without a security environment - but there isn't really 269 * a way to specify the security environment in PKCS15. 270 * What I'm doing here (for now) is to assume that for a key 271 * object with ID 0xNN there is always a corresponding SE object 272 * with the same ID. 273 * XXX Need to find out how the Aladdin drivers do it. 274 */ 275 static int itacns_set_security_env(sc_card_t *card, 276 const sc_security_env_t *env, int se_num) 277 { 278 sc_apdu_t apdu; 279 u8 data[3]; 280 int key_id, r; 281 282 assert(card != NULL && env != NULL); 283 284 if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) 285 || env->key_ref_len != 1) { 286 sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No or invalid key reference\n"); 287 return SC_ERROR_INVALID_ARGUMENTS; 288 } 289 key_id = env->key_ref[0]; 290 291 /* CIE v1 cards need to restore security environment 0x30; all the others 292 so far want 0x03. */ 293 r = itacns_restore_security_env(card, (card->type == SC_CARD_TYPE_ITACNS_CIE_V1 294 ? 0x30 : 0x03)); 295 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 296 297 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF1, 0); 298 switch (env->operation) { 299 case SC_SEC_OPERATION_DECIPHER: 300 apdu.p2 = 0xB8; 301 break; 302 case SC_SEC_OPERATION_SIGN: 303 apdu.p2 = 0xB6; 304 break; 305 case SC_SEC_OPERATION_AUTHENTICATE: 306 apdu.p2 = 0xA4; 307 break; 308 default: 309 return SC_ERROR_INVALID_ARGUMENTS; 310 } 311 312 sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Setting sec env for key_id=%d\n", key_id); 313 314 data[0] = 0x83; 315 data[1] = 0x01; 316 data[2] = key_id; 317 apdu.lc = apdu.datalen = 3; 318 apdu.data = data; 319 320 r = sc_transmit_apdu(card, &apdu); 321 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 322 323 r = sc_check_sw(card, apdu.sw1, apdu.sw2); 324 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); 325 326 SC_FUNC_RETURN(card->ctx, 1, r); 327 } 328 329 /* 330 * The 0x80 thing tells the card it's okay to search parent 331 * directories as well for the referenced object. 332 * This is necessary for some Italian CNS cards, and to be avoided 333 * for others. Right now it seems that it is only needed with 334 * cards by STIncard. 335 */ 336 static int 337 itacns_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, 338 int *tries_left) 339 { 340 data->flags |= SC_PIN_CMD_NEED_PADDING; 341 /* Enable backtracking for STIncard cards. */ 342 if(DRVDATA(card)->mask_manufacturer_code == ITACNS_MASKMAN_STINCARD) { 343 data->pin_reference |= 0x80; 344 } 345 346 /* FIXME: the following values depend on what pin length was 347 * used when creating the BS objects */ 348 if (data->pin1.max_length == 0) 349 data->pin1.max_length = 8; 350 if (data->pin2.max_length == 0) 351 data->pin2.max_length = 8; 352 return default_ops->pin_cmd(card, data, tries_left); 353 } 354 355 static int itacns_read_binary(sc_card_t *card, 356 unsigned int idx, u8 *buf, size_t count, 357 unsigned long flags) 358 { 359 size_t already_read = 0; 360 size_t requested; 361 int r; 362 while(1) { 363 requested = count - already_read; 364 if(requested > ITACNS_MAX_PAYLOAD) requested = ITACNS_MAX_PAYLOAD; 365 r = default_ops->read_binary(card, idx+already_read, &buf[already_read], 366 requested, flags); 367 if(r < 0) return r; 368 already_read += r; 369 if (r == 0 || r < requested || already_read == count) { 370 /* We have finished */ 371 return already_read; 372 } 373 } 374 } 375 376 static int itacns_list_files(sc_card_t *card, u8 *buf, size_t buflen) { 377 struct sc_card_operations *list_ops; 378 379 if (DRVDATA(card) && DRVDATA(card)->mask_manufacturer_code == ITACNS_MASKMAN_SIEMENS) { 380 list_ops = sc_get_cardos_driver()->ops; 381 } else { 382 list_ops = sc_get_incrypto34_driver()->ops; 383 } 384 return list_ops->list_files(card, buf, buflen); 385 } 386 387 static void add_acl_entry(sc_file_t *file, int op, u8 byte) 388 { 389 unsigned int method, key_ref = SC_AC_KEY_REF_NONE; 390 391 switch (byte) { 392 case 0x00: 393 method = SC_AC_NONE; 394 break; 395 case 0xFF: 396 case 0x66: 397 method = SC_AC_NEVER; 398 break; 399 default: 400 if (byte > 0x1F) { 401 method = SC_AC_UNKNOWN; 402 } else { 403 method = SC_AC_CHV; 404 key_ref = byte; 405 } 406 break; 407 } 408 sc_file_add_acl_entry(file, op, method, key_ref); 409 } 410 411 static const int df_acl[9] = { 412 -1, /* LCYCLE (life cycle change) */ 413 SC_AC_OP_UPDATE, /* UPDATE Objects */ 414 SC_AC_OP_WRITE, /* APPEND Objects */ 415 416 SC_AC_OP_INVALIDATE, /* DF */ 417 SC_AC_OP_REHABILITATE, /* DF */ 418 SC_AC_OP_DELETE, /* DF */ 419 420 SC_AC_OP_WRITE, /* ADMIN DF */ 421 SC_AC_OP_CREATE, /* Files */ 422 -1 /* Reserved */ 423 }; 424 static const int ef_acl[9] = { 425 SC_AC_OP_READ, /* Data */ 426 SC_AC_OP_UPDATE, /* Data (write file content) */ 427 SC_AC_OP_WRITE, /* */ 428 429 SC_AC_OP_INVALIDATE, /* EF */ 430 SC_AC_OP_REHABILITATE, /* EF */ 431 SC_AC_OP_ERASE, /* (delete) EF */ 432 433 /* XXX: ADMIN should be an ACL type of its own, or mapped 434 * to erase */ 435 SC_AC_OP_ERASE, /* ADMIN EF (modify meta information?) */ 436 -1, /* INC (-> cylic fixed files) */ 437 -1 /* DEC */ 438 }; 439 440 static void parse_sec_attr(sc_file_t *file, const u8 *buf, size_t len) 441 { 442 size_t i; 443 const int *idx; 444 445 idx = (file->type == SC_FILE_TYPE_DF) ? df_acl : ef_acl; 446 447 /* acl defaults to 0xFF if unspecified */ 448 for (i = 0; i < 9; i++) 449 if (idx[i] != -1) 450 add_acl_entry(file, idx[i], (u8)((i < len) ? buf[i] : 0xFF)); 451 } 452 453 static int itacns_select_file(sc_card_t *card, 454 const sc_path_t *in_path, 455 sc_file_t **file) 456 { 457 int r; 458 459 SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); 460 r = default_ops->select_file(card, in_path, file); 461 if (r >= 0 && file) 462 parse_sec_attr((*file), (*file)->sec_attr, (*file)->sec_attr_len); 463 SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); 464 } 465 466 467 static struct sc_card_driver * sc_get_driver(void) 468 { 469 if (!default_ops) 470 default_ops = sc_get_iso7816_driver()->ops; 471 itacns_ops = *default_ops; 472 itacns_ops.match_card = itacns_match_card; 473 itacns_ops.init = itacns_init; 474 itacns_ops.finish = itacns_finish; 475 itacns_ops.set_security_env = itacns_set_security_env; 476 itacns_ops.restore_security_env = itacns_restore_security_env; 477 itacns_ops.pin_cmd = itacns_pin_cmd; 478 itacns_ops.read_binary = itacns_read_binary; 479 itacns_ops.list_files = itacns_list_files; 480 itacns_ops.select_file = itacns_select_file; 481 return &itacns_drv; 482 } 483 484 struct sc_card_driver * sc_get_itacns_driver(void) 485 { 486 return sc_get_driver(); 487 } -
src/libopensc/cards.h
diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index b5d8bda..843a762 100644
a b enum { 167 167 /* Generic JavaCards without supported applet */ 168 168 SC_CARD_TYPE_JAVACARD_BASE = 23000, 169 169 SC_CARD_TYPE_JAVACARD, 170 171 /* Italian CNS cards */ 172 SC_CARD_TYPE_ITACNS_BASE = 24000, 173 SC_CARD_TYPE_ITACNS_GENERIC, 174 SC_CARD_TYPE_ITACNS_CNS, 175 SC_CARD_TYPE_ITACNS_CIE_V2, 176 SC_CARD_TYPE_ITACNS_CIE_V1, 177 170 178 }; 171 179 172 180 extern sc_card_driver_t *sc_get_default_driver(void); … … extern sc_card_driver_t *sc_get_westcos_driver(void); 198 206 extern sc_card_driver_t *sc_get_myeid_driver(void); 199 207 extern sc_card_driver_t *sc_get_ias_driver(void); 200 208 extern sc_card_driver_t *sc_get_javacard_driver(void); 209 extern sc_card_driver_t *sc_get_itacns_driver(void); 201 210 202 211 #ifdef __cplusplus 203 212 } -
src/libopensc/ctx.c
diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 4158d87..becd065 100644
a b static const struct _sc_driver_entry internal_card_drivers[] = { 93 93 #endif 94 94 /* javacard without supported applet - last before default */ 95 95 { "javacard", (void *(*)(void)) sc_get_javacard_driver }, 96 96 { "itacns", (void *(*)(void)) sc_get_itacns_driver }, 97 97 /* The default driver should be last, as it handles all the 98 98 * unrecognized cards. */ 99 99 { "default", (void *(*)(void)) sc_get_default_driver }, -
src/libopensc/iso7816.c
diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 9d826ad..52d10af 100644
a b static int iso7816_get_challenge(sc_card_t *card, u8 *rnd, size_t len) 520 520 return 0; 521 521 } 522 522 523 /* This belongs to ETSI TS 101 206-3, not to ISO 7816. */ 524 static int iso7816_give_random(sc_card_t *card, u8 *rnd, size_t len) 525 { 526 int r; 527 sc_apdu_t apdu; 528 529 sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 530 0x86, 0x00, 0x00); 531 apdu.cla = 0x80; 532 apdu.data = rnd; 533 apdu.lc = apdu.datalen = len; 534 535 r = sc_transmit_apdu(card, &apdu); 536 SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 537 return sc_check_sw(card, apdu.sw1, apdu.sw2); 538 } 539 523 540 static int iso7816_construct_fci(sc_card_t *card, const sc_file_t *file, 524 541 u8 *out, size_t *outlen) 525 542 { … … static struct sc_card_operations iso_ops = { 1001 1018 iso7816_select_file, 1002 1019 iso7816_get_response, 1003 1020 iso7816_get_challenge, 1021 iso7816_give_random, 1004 1022 NULL, /* verify */ 1005 1023 NULL, /* logout */ 1006 1024 iso7816_restore_security_env, -
new file src/libopensc/itacns.h
diff --git a/src/libopensc/itacns.h b/src/libopensc/itacns.h new file mode 100644 index 0000000..742627b
- + 1 #ifndef _OPENSC_ITACNS_H 2 #define _OPENSC_ITACNS_H 3 4 typedef struct { 5 u8 ic_manufacturer_code; 6 u8 mask_manufacturer_code; 7 u8 os_version_h; 8 u8 os_version_l; 9 u8 cns_version; 10 } itacns_drv_data_t; 11 12 #define ITACNS_MASKMAN_SIEMENS 0x08 13 #define ITACNS_MASKMAN_STINCARD 0x09 14 15 #endif /* _OPENSC_ITACNS_H */ -
src/libopensc/opensc.h
diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 7d95488..796cef0 100644
a b struct sc_card_operations { 441 441 struct sc_file **file_out); 442 442 int (*get_response)(struct sc_card *card, size_t *count, u8 *buf); 443 443 int (*get_challenge)(struct sc_card *card, u8 * buf, size_t count); 444 /* This belongs to ETSI TS 101 206-3, not to ISO 7816. */ 445 int (*give_random)(struct sc_card *card, u8 * buf, size_t count); 444 446 445 447 /* 446 448 * ISO 7816-8 functions -
new file src/libopensc/pkcs15-itacns.c
diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c new file mode 100644 index 0000000..83fd6b0
- + 1 /* 2 * PKCS15 emulation layer for Italian CNS. 3 * 4 * Copyright (C) 2008, Emanuele Pucciarelli <ep@acm.org> 5 * Many snippets have been taken out from other PKCS15 emulation layer 6 * modules in this directory; their copyright is their authors'. 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 */ 22 23 /* 24 * Specifications for the development of this driver come from: 25 * http://www.servizidemografici.interno.it/sitoCNSD/documentazioneRicerca.do?metodo=contenutoDocumento&servizio=documentazione&ID_DOCUMENTO=1043 26 */ 27 28 29 #ifdef HAVE_CONFIG_H 30 #include <config.h> 31 #endif 32 33 #include "pkcs15.h" 34 #include "log.h" 35 #include "cards.h" 36 #include "itacns.h" 37 #include <stdlib.h> 38 #include <string.h> 39 #include <stdio.h> 40 #include "common/compat_strlcpy.h" 41 42 #ifdef ENABLE_OPENSSL 43 #include <openssl/x509v3.h> 44 #endif 45 46 int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, 47 sc_pkcs15emu_opt_t *); 48 49 static const char path_serial[] = "10001003"; 50 static const char path_personal_data[] = "11001102"; 51 52 /* Manufacturers */ 53 54 char * itacns_mask_manufacturers[] = { 55 "Unknown", 56 "Kaitech", 57 "Gemplus", 58 "Ghirlanda", 59 "Giesecke & Devrient", 60 "Oberthur Card Systems", 61 "Orga", 62 "Axalto", 63 "Siemens", 64 "STIncard", 65 "GEP", 66 "EPS Corp", 67 "Athena" 68 }; 69 70 char * iso7816_ic_manufacturers[] = { 71 "Unknown", 72 "Motorola", 73 "STMicroelectronics", 74 "Hitachi", 75 "Philips Semiconductors", 76 "Siemens", 77 "Cylinc", 78 "Texas Instruments", 79 "Fujitsu", 80 "Matsushita", 81 "NEC", 82 "Oki", 83 "Toshiba", 84 "Mitsubishi", 85 "Samsung", 86 "Hyundai", 87 "LG" 88 }; 89 90 /* Data files */ 91 92 static const struct { 93 char *label; 94 char *path; 95 int cie_only; 96 } itacns_data_files[] = { 97 { "EF_DatiProcessore", "3F0010001002", 0 }, 98 { "EF_IDCarta", "3F0010001003", 0 }, 99 { "EF_DatiSistema", "3F0010001004", 1 }, 100 { "EF_DatiPersonali", "3F0011001102", 0 }, 101 { "EF_DatiPersonali_Annotazioni", "3F0011001103", 1 }, 102 { "EF_Impronte", "3F0011001104", 1 }, 103 { "EF_Foto", "3F0011001104", 1 }, 104 { "EF_DatiPersonaliAggiuntivi", "3F0012001201", 0 }, 105 { "EF_MemoriaResidua", "3F0012001202", 0 }, 106 { "EF_ServiziInstallati", "3F0012001203", 0 }, 107 { "EF_INST_FILE", "3F0012004142", 0 }, 108 { "EF_CardStatus", "3F003F02", 0 }, 109 { "EF_GDO", "3F002F02", 0 }, 110 { "EF_RootInstFile", "3F000405", 0 } 111 }; 112 113 114 /* 115 * Utility functions 116 */ 117 118 static void set_string(char **strp, const char *value) 119 { 120 if (*strp) 121 free(*strp); 122 *strp = value ? strdup(value) : NULL; 123 } 124 125 static int loadFile(const sc_pkcs15_card_t *p15card, const sc_path_t *path, 126 u8 *buf, const size_t buflen) 127 { 128 SC_FUNC_CALLED(p15card->card->ctx, 1); 129 130 int sc_res; 131 sc_res = sc_select_file(p15card->card, path, NULL); 132 if(sc_res != SC_SUCCESS) 133 return sc_res; 134 135 sc_res = sc_read_binary(p15card->card, 0, buf, buflen, 0); 136 return sc_res; 137 } 138 139 /* 140 * The following functions add objects to the card emulator. 141 */ 142 143 static int itacns_add_cert(sc_pkcs15_card_t *p15card, 144 int type, int authority, const sc_path_t *path, 145 const sc_pkcs15_id_t *id, const char *label, int obj_flags, 146 int *ext_info_ok, int *key_usage, int *x_key_usage) 147 { 148 SC_FUNC_CALLED(p15card->card->ctx, 1); 149 int r; 150 *ext_info_ok = 0; 151 152 /* const char *label = "Certificate"; */ 153 sc_pkcs15_cert_info_t info; 154 sc_pkcs15_object_t obj; 155 156 memset(&info, 0, sizeof(info)); 157 memset(&obj, 0, sizeof(obj)); 158 159 info.id = *id; 160 info.authority = authority; 161 if (path) 162 info.path = *path; 163 164 strlcpy(obj.label, label, sizeof(obj.label)); 165 obj.flags = obj_flags; 166 167 r = sc_pkcs15emu_add_x509_cert(p15card, &obj, &info); 168 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add X.509 certificate"); 169 170 /* If we have OpenSSL, read keyUsage */ 171 #ifdef ENABLE_OPENSSL 172 173 X509 *x509; 174 sc_pkcs15_cert_t *cert; 175 176 r = sc_pkcs15_read_certificate(p15card, &info, &cert); 177 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not read X.509 certificate"); 178 179 const u8 *throwaway = cert->data; 180 x509 = d2i_X509(NULL, &throwaway, cert->data_len); 181 sc_pkcs15_free_certificate(cert); 182 if (!x509) return SC_SUCCESS; 183 X509_check_purpose(x509, -1, 0); 184 if(x509->ex_flags & EXFLAG_KUSAGE) { 185 *ext_info_ok = 1; 186 *key_usage = x509->ex_kusage; 187 *x_key_usage = x509->ex_xkusage; 188 } 189 OPENSSL_free(x509); 190 191 return SC_SUCCESS; 192 193 #else /* ENABLE_OPENSSL */ 194 195 return SC_SUCCESS; 196 197 #endif /* ENABLE_OPENSSL */ 198 199 } 200 201 static int itacns_add_pubkey(sc_pkcs15_card_t *p15card, 202 const sc_path_t *path, const sc_pkcs15_id_t *id, const char *label, 203 int usage, int ref, int obj_flags, int *modulus_len_out) 204 { 205 SC_FUNC_CALLED(p15card->card->ctx, 1); 206 207 int r; 208 sc_pkcs15_pubkey_info_t info; 209 sc_pkcs15_object_t obj; 210 211 memset(&info, 0, sizeof(info)); 212 memset(&obj, 0, sizeof(obj)); 213 214 info.id = *id; 215 if (path) 216 info.path = *path; 217 info.usage = usage; 218 info.key_reference = ref; 219 strlcpy(obj.label, label, sizeof(obj.label)); 220 obj.flags = obj_flags; 221 222 /* This is hard-coded, unless weird versions of the CNS turn up sometime. */ 223 info.modulus_length = 1024; 224 225 *modulus_len_out = info.modulus_length; 226 r = sc_pkcs15emu_add_rsa_pubkey(p15card, &obj, &info); 227 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add pub key"); 228 return r; 229 } 230 231 static int itacns_add_prkey(sc_pkcs15_card_t *p15card, 232 const sc_pkcs15_id_t *id, 233 const char *label, 234 int type, unsigned int modulus_length, int usage, 235 int algo_flags, const sc_path_t *path, int ref, 236 const sc_pkcs15_id_t *auth_id, int obj_flags) 237 { 238 SC_FUNC_CALLED(p15card->card->ctx, 1); 239 240 sc_pkcs15_prkey_info_t info; 241 sc_pkcs15_object_t obj; 242 243 memset(&info, 0, sizeof(info)); 244 memset(&obj, 0, sizeof(obj)); 245 246 info.id = *id; 247 info.modulus_length = modulus_length; 248 info.usage = usage; 249 info.native = 1; 250 info.key_reference = ref; 251 info.access_flags = 252 SC_PKCS15_PRKEY_ACCESS_SENSITIVE 253 | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE 254 | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE 255 | SC_PKCS15_PRKEY_ACCESS_LOCAL; 256 257 if (path) 258 info.path = *path; 259 260 obj.flags = obj_flags; 261 strlcpy(obj.label, label, sizeof(obj.label)); 262 if (auth_id != NULL) 263 obj.auth_id = *auth_id; 264 265 return sc_pkcs15emu_add_rsa_prkey(p15card, &obj, &info); 266 } 267 268 static int itacns_add_pin(sc_pkcs15_card_t *p15card, 269 char *label, 270 int id, 271 int auth_id, 272 int reference, 273 sc_path_t *path, 274 int flags) 275 { 276 SC_FUNC_CALLED(p15card->card->ctx, 1); 277 278 struct sc_pkcs15_pin_info pin_info; 279 struct sc_pkcs15_object pin_obj; 280 281 memset(&pin_info, 0, sizeof(pin_info)); 282 pin_info.auth_id.len = 1; 283 pin_info.auth_id.value[0] = id; 284 pin_info.reference = reference; 285 pin_info.flags = flags; 286 pin_info.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; 287 pin_info.min_length = 5; 288 pin_info.stored_length = 8; 289 pin_info.max_length = 8; 290 pin_info.pad_char = 0xff; 291 if(path) 292 pin_info.path = *path; 293 294 memset(&pin_obj, 0, sizeof(pin_obj)); 295 strlcpy(pin_obj.label, label, sizeof(pin_obj.label)); 296 pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE | (auth_id ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0); 297 if (auth_id) { 298 pin_obj.auth_id.len = 1; 299 pin_obj.auth_id.value[0] = auth_id; 300 } else 301 pin_obj.auth_id.len = 0; 302 303 return sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); 304 } 305 306 static int itacns_add_data_files(sc_pkcs15_card_t *p15card) 307 { 308 const size_t list_size = sizeof(itacns_data_files)/sizeof(itacns_data_files[0]); 309 int i; 310 int r; 311 for(i=0; i < list_size; i++) { 312 if(itacns_data_files[i].cie_only && 313 p15card->card->type != SC_CARD_TYPE_ITACNS_CIE_V2) 314 continue; 315 316 sc_path_t path; 317 318 sc_format_path(itacns_data_files[i].path, &path); 319 sc_pkcs15_data_info_t data; 320 sc_pkcs15_object_t obj; 321 322 memset(&data, 0, sizeof(data)); 323 memset(&obj, 0, sizeof(obj)); 324 strlcpy(data.app_label, itacns_data_files[i].label, 325 sizeof(data.app_label)); 326 strlcpy(obj.label, itacns_data_files[i].label, 327 sizeof(obj.label)); 328 data.path = path; 329 r = sc_pkcs15emu_add_data_object(p15card, &obj, &data); 330 } 331 return SC_SUCCESS; 332 } 333 334 static int itacns_add_keyset(sc_pkcs15_card_t *p15card, 335 const char *label, int sec_env, sc_pkcs15_id_t *cert_id, 336 const char *pubkey_path, const char *prkey_path, 337 unsigned int pubkey_usage_flags, unsigned int prkey_usage_flags, 338 u8 pin_ref, int needs_enc) 339 { 340 int r; 341 sc_path_t path; 342 343 /* This is hard-coded, for the time being. */ 344 int modulus_length = 1024; 345 346 /* Access flags; these depend on whether the private keys use PSO_ENC 347 or PSO_CDS for signing. */ 348 349 const int enc_algo_flags = SC_ALGORITHM_NEED_USAGE 350 | SC_ALGORITHM_RSA_RAW 351 | SC_ALGORITHM_RSA_HASH_NONE; 352 const int cds_algo_flags = SC_ALGORITHM_NEED_USAGE 353 | SC_ALGORITHM_RSA_PAD_PKCS1 354 | SC_ALGORITHM_RSA_HASH_NONE; 355 356 /* Public key; not really needed */ 357 /* FIXME: set usage according to the certificate. */ 358 if (pubkey_path) { 359 sc_format_path(pubkey_path, &path); 360 r = itacns_add_pubkey(p15card, &path, cert_id, label, 361 pubkey_usage_flags, sec_env, 0, &modulus_length); 362 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add public key"); 363 } 364 365 /* FIXME: usage should be inferred from the X.509 certificate, and not 366 from whether the key needs Secure Messaging. */ 367 sc_path_t *private_path = NULL; 368 if (prkey_path) { 369 sc_format_path(prkey_path, &path); 370 private_path = &path; 371 } 372 r = itacns_add_prkey(p15card, cert_id, label, SC_PKCS15_TYPE_PRKEY_RSA, 373 modulus_length, 374 prkey_usage_flags, 375 (needs_enc ? enc_algo_flags : cds_algo_flags), 376 private_path, sec_env, cert_id, SC_PKCS15_CO_FLAG_PRIVATE); 377 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add private key"); 378 379 /* PIN and PUK */ 380 char pinlabel[16]; 381 strncpy(pinlabel, "PIN ", sizeof(pinlabel)); 382 strncat(pinlabel, label, sizeof(pinlabel)); 383 /* We are making up ID 0x90+ to link the PIN and the PUK. */ 384 int fake_puk_authid = 0x90 + pin_ref; 385 int pin_flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE 386 | SC_PKCS15_PIN_FLAG_INITIALIZED; 387 388 r = itacns_add_pin(p15card, pinlabel, sec_env, fake_puk_authid, pin_ref, 389 private_path, pin_flags); 390 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add PIN"); 391 392 strncpy(pinlabel, "PUK ", sizeof(pinlabel)); 393 strncat(pinlabel, label, sizeof(pinlabel)); 394 /* 395 * Looking at pkcs15-tcos.c and pkcs15-framework.c, it seems that the 396 * right thing to do here is to define a PUK as a SO PIN. Can anybody 397 * comment on this? 398 */ 399 pin_flags |= SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN 400 | SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED; 401 r = itacns_add_pin(p15card, pinlabel, fake_puk_authid, 0, pin_ref+1, 402 private_path, pin_flags); 403 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add PUK"); 404 405 return 0; 406 } 407 408 /* 409 * itacns_check_and_add_keyset() checks for the existence and correctness 410 * of an X.509 certificate. If it is all right, it adds the related keys; 411 * otherwise it aborts. 412 */ 413 414 static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, 415 const char *label, int sec_env, size_t cert_offset, 416 const char *cert_path, const char *pubkey_path, const char *prkey_path, 417 u8 pin_ref, int needs_enc, int *found_certificates) 418 { 419 int r; 420 sc_path_t path; 421 sc_pkcs15_id_t cert_id; 422 423 cert_id.len = 1; 424 cert_id.value[0] = sec_env; 425 *found_certificates = 0; 426 427 /* Usage flags */ 428 const int auth_pubkey_usage_flags = SC_PKCS15_PRKEY_USAGE_ENCRYPT 429 | SC_PKCS15_PRKEY_USAGE_DECRYPT 430 | SC_PKCS15_PRKEY_USAGE_WRAP 431 | SC_PKCS15_PRKEY_USAGE_VERIFY; 432 const int auth_prkey_usage_flags = SC_PKCS15_PRKEY_USAGE_DECRYPT 433 | SC_PKCS15_PRKEY_USAGE_UNWRAP 434 | SC_PKCS15_PRKEY_USAGE_SIGN; 435 const int sig_pubkey_usage_flags = SC_PKCS15_PRKEY_USAGE_VERIFY; 436 const int sig_prkey_usage_flags = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; 437 438 /* Certificate */ 439 if (!cert_path) { 440 sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 441 "We cannot use keys without a matching certificate"); 442 return SC_ERROR_NOT_SUPPORTED; 443 } 444 445 sc_format_path(cert_path, &path); 446 r = sc_select_file(p15card->card, &path, NULL); 447 if (r == SC_ERROR_FILE_NOT_FOUND) 448 return 0; 449 if (r != SC_SUCCESS) { 450 sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 451 "Could not find certificate for %s", label); 452 return r; 453 } 454 455 /* 456 * Infocamere 1204 (and others?) store a more complex structure. We 457 * are going to read the first bytes to guess its length, and invoke 458 * itacns_add_cert so that it only reads the certificate. 459 */ 460 if (cert_offset) { 461 u8 certlen[3]; 462 r = loadFile(p15card, &path, certlen, sizeof(certlen)); 463 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not read certificate file"); 464 path.index = cert_offset; 465 path.count = (certlen[1] << 8) + certlen[2]; 466 /* If those bytes are 00, then we are probably dealign with an 467 * empty file. */ 468 if (path.count == 0) 469 return 0; 470 } 471 int ext_info_ok; 472 int ku, xku; 473 r = itacns_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, 0, 474 &path, &cert_id, label, 0, &ext_info_ok, &ku, &xku); 475 if (r == SC_ERROR_INVALID_ASN1_OBJECT) 476 return 0; 477 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add certificate"); 478 (*found_certificates)++; 479 480 /* Set usage flags */ 481 int pubkey_usage_flags = 0, prkey_usage_flags = 0; 482 if(ext_info_ok) { 483 #ifdef ENABLE_OPENSSL 484 if (ku & KU_DIGITAL_SIGNATURE) { 485 pubkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_VERIFY; 486 prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_SIGN; 487 } 488 if (ku & KU_NON_REPUDIATION) { 489 pubkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_VERIFY; 490 prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; 491 } 492 if (ku & KU_KEY_ENCIPHERMENT || ku & KU_KEY_AGREEMENT 493 || xku & XKU_SSL_CLIENT) { 494 pubkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_WRAP; 495 prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_UNWRAP; 496 } 497 if (ku & KU_DATA_ENCIPHERMENT || xku & XKU_SMIME) { 498 pubkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_ENCRYPT; 499 prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_DECRYPT; 500 } 501 #else /* ENABLE_OPENSSL */ 502 sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Extended certificate " 503 "info retrieved without OpenSSL. How is this possible?"); 504 return SC_ERROR_INTERNAL; 505 #endif /* ENABLE_OPENSSL */ 506 } else { 507 /* Certificate info not retrieved; fall back onto defaults */ 508 pubkey_usage_flags = SC_PKCS15_PRKEY_USAGE_VERIFY | SC_PKCS15_PRKEY_USAGE_WRAP; 509 prkey_usage_flags = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_UNWRAP; 510 } 511 512 r = itacns_add_keyset(p15card, label, sec_env, &cert_id, 513 pubkey_path, prkey_path, pubkey_usage_flags, prkey_usage_flags, 514 pin_ref, needs_enc); 515 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add keys for" 516 " this certificate"); 517 518 return r; 519 } 520 521 /* Initialization. */ 522 523 static int itacns_init(sc_pkcs15_card_t *p15card) 524 { 525 SC_FUNC_CALLED(p15card->card->ctx, 1); 526 527 int r; 528 sc_path_t path; 529 int certificate_count = 0; 530 int found_certs; 531 532 set_string(&p15card->label, p15card->card->name); 533 if(p15card->card->drv_data) { 534 int mask_code, ic_code; 535 char buffer[256]; 536 itacns_drv_data_t *data = (itacns_drv_data_t*) p15card->card->drv_data; 537 mask_code = data->mask_manufacturer_code; 538 if (mask_code >= sizeof(itacns_mask_manufacturers)) 539 mask_code = 0; 540 ic_code = data->ic_manufacturer_code; 541 if (ic_code >= sizeof(iso7816_ic_manufacturers)) 542 ic_code = 0; 543 snprintf(buffer, sizeof(buffer), "IC: %s; mask: %s", 544 iso7816_ic_manufacturers[ic_code], 545 itacns_mask_manufacturers[mask_code]); 546 set_string(&p15card->manufacturer_id, buffer); 547 p15card->version = (data->os_version_h << 8 | data->os_version_l); 548 } 549 550 /* Read and set serial */ 551 u8 serial[17]; 552 { 553 int bytes; 554 sc_format_path(path_serial, &path); 555 bytes = loadFile(p15card, &path, serial, 16); 556 if (bytes < 0) return bytes; 557 if (bytes > 16) return -1; 558 serial[bytes] = '\0'; 559 set_string(&p15card->serial_number, (char*)serial); 560 } 561 562 /* Is the card a CIE v1? */ 563 int card_is_cie_v1 = (p15card->card->type == SC_CARD_TYPE_ITACNS_CIE_V1) 564 || (p15card->card->type == SC_CARD_TYPE_CARDOS_CIE_V1); 565 int cns0_secenv = (card_is_cie_v1 ? 0x31 : 0x01); 566 567 /* If it's a Siemens CIE v1 card, set algo flags accordingly. */ 568 if (card_is_cie_v1) { 569 int i; 570 for (i = 0; i < p15card->card->algorithm_count; i++) { 571 sc_algorithm_info_t *info = &p15card->card->algorithms[i]; 572 573 if (info->algorithm != SC_ALGORITHM_RSA) 574 continue; 575 info->flags &= ~(SC_ALGORITHM_RSA_RAW 576 | SC_ALGORITHM_RSA_HASH_NONE); 577 info->flags |= (SC_ALGORITHM_RSA_PAD_PKCS1 578 | SC_ALGORITHM_RSA_HASHES); 579 } 580 } 581 582 /*** Certificate and keys. ***/ 583 /* Standard CNS */ 584 r = itacns_check_and_add_keyset(p15card, "CNS0", cns0_secenv, 585 0, "3F0011001101", "3F003F01", NULL, 586 0x10, !card_is_cie_v1, &found_certs); 587 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add CNS0"); 588 certificate_count += found_certs; 589 590 /* Infocamere 1204 */ 591 r = itacns_check_and_add_keyset(p15card, "CNS01", 0x21, 592 5, "3F002FFF8228", NULL, "3F002FFF0000", 593 0x10, 1, &found_certs); 594 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add CNS01"); 595 certificate_count += found_certs; 596 597 /* Digital signature */ 598 r = itacns_check_and_add_keyset(p15card, "CNS1", 0x10, 599 0, "3F0014009010", "3F00140081108010", "3F0014008110", 600 0x1a, 0, &found_certs); 601 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add CNS1"); 602 certificate_count += found_certs; 603 604 /* Did we find anything? */ 605 if (certificate_count == 0) 606 sc_debug(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, "Warning: no certificates found!"); 607 608 /* Data files */ 609 r = itacns_add_data_files(p15card); 610 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add data files"); 611 612 /* Back to Master File */ 613 sc_format_path("3F00", &path); 614 r = sc_select_file(p15card->card, &path, NULL); 615 SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not select master file again"); 616 617 return r; 618 } 619 620 int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, 621 sc_pkcs15emu_opt_t *opts) 622 { 623 sc_card_t *card = p15card->card; 624 SC_FUNC_CALLED(card->ctx, 1); 625 626 /* Check card */ 627 if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { 628 if (! ( 629 (card->type > SC_CARD_TYPE_ITACNS_BASE && 630 card->type < SC_CARD_TYPE_ITACNS_BASE + 1000) 631 || card->type == SC_CARD_TYPE_CARDOS_CIE_V1) 632 ) 633 return SC_ERROR_WRONG_CARD; 634 } 635 636 /* Init card */ 637 return itacns_init(p15card); 638 } -
src/libopensc/pkcs15-syn.c
diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index d107cba..81bf45e 100644
a b extern int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); 63 63 64 64 extern int sc_pkcs15emu_oberthur_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); 65 65 66 extern int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); 67 66 68 static struct { 67 69 const char * name; 68 70 int (*handler)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); … … static struct { 73 75 { "starcert", sc_pkcs15emu_starcert_init_ex }, 74 76 { "tcos", sc_pkcs15emu_tcos_init_ex }, 75 77 { "esteid", sc_pkcs15emu_esteid_init_ex }, 78 { "itacns", sc_pkcs15emu_itacns_init_ex }, 76 79 { "postecert", sc_pkcs15emu_postecert_init_ex }, 77 80 { "PIV-II", sc_pkcs15emu_piv_init_ex }, 78 81 { "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex },
