From 02cc450be0e971d11a651ab0b9856aeaff683334 Mon Sep 17 00:00:00 2001 From: nils Date: Fri, 9 Sep 2005 19:30:43 +0000 Subject: [PATCH] update tcos pkcs15 emulation drivers; patch supplied by Peter Koch git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@2565 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/pkcs15-netkey.c | 333 +++++++++++++++++----------------- 1 file changed, 166 insertions(+), 167 deletions(-) diff --git a/src/libopensc/pkcs15-netkey.c b/src/libopensc/pkcs15-netkey.c index 28104602..3e1c75c7 100644 --- a/src/libopensc/pkcs15-netkey.c +++ b/src/libopensc/pkcs15-netkey.c @@ -1,7 +1,7 @@ /* - * PKCS15 emulation layer for Telesec Netkey E4 card. + * PKCS15 emulation layer for TCOS base preformatted cards * - * Copyright (C) 2004, Peter Koch + * Copyright (C) 2005, Peter Koch * Copyright (C) 2004, Antonino Iacono * Copyright (C) 2003, Olaf Kirch * @@ -27,67 +27,93 @@ #include #include -int sc_pkcs15emu_netkey_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); - static void set_string(char **strp, const char *value) { if (*strp) free(*strp); - *strp = value? strdup(value) : NULL; + *strp = value ? strdup(value) : NULL; } -static int -sc_pkcs15emu_netkey_init(sc_pkcs15_card_t *p15card) { +int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *p15card, sc_pkcs15emu_opt_t *opts) +{ static const struct { - int id, auth_id; - int min_length; + char *card, *manufacturer; + } cardlist[]={ + {"Netkey E4 Card", "TeleSec GmbH"}, + {"SignTrust Card", "Deutsche Post"}, + {"Smartkey Card", "Kobil GmbH"} + }; + static const struct { + int type, id, writable; + const char *path; + const char *label; + } certlist[]={ + { 1, 1, 0, "DF01C000", "Telesec Signatur Zertifikat"}, + {-1, 2, 1, "DF014331", "Signatur Zertifikat 1"}, + {-1, 3, 1, "DF014332", "Signatur Zertifikat 2"}, + {-1, 4, 0, "DF01C100", "Telesec Authentifizierungs Zertifikat"}, + {-1, 5, 1, "DF014371", "Authentifizierungs Zertifikat 1"}, + {-1, 6, 1, "DF014372", "Authentifizierungs Zertifikat 2"}, + {-1, 7, 0, "DF01C200", "Telesec Verschlüsselungs Zertifikat"}, + {-1, 8, 1, "DF0143B1", "Verschlüsselungs Zertifikat 1"}, + {-1, 9, 1, "DF0143B2", "Verschlüsselungs Zertifikat 2"}, + { 2, 10, 1, "8000DF01C000", "SignTrust Signatur Zertifikat"}, + { 2, 11, 1, "800082008220", "SignTrust Authentifizierungs Zertifikat"}, + { 2, 12, 1, "800083008320", "SignTrust Verschlüsselungs Zertifikat"}, + {-1, 13, 1, "41014352", "W2K Logon Zertifikat"}, + { 3, 14, 1, "42014352", "W2K Logon Zertifikat"}, + { 3, 15, 1, "43014352", "Smartkey Zertifikat 1"}, + { 3, 16, 1, "43014353", "Smartkey Zertifikat 2"}, + { 0, 0, 0, NULL, NULL} + }; + static const struct { + int type, id, auth_id; + const char *path; + unsigned char key_reference; + const char *label; + } keylist[]={ + {1, 1, 4, "DF015331", 0x80, "Signatur Schlüssel"}, + {1, 4, 4, "DF015371", 0x82, "Authentifizierungs Schlüssel"}, + {1, 7, 3, "DF0153B1", 0x81, "Verschlüsselungs Schlüssel"}, + {2, 10, 5, "8000DF015331", 0x80, "Signatur Schlüssel"}, + {2, 11, 6, "800082008210", 0x80, "Authentifzierungs Schlüssel"}, + {2, 12, 7, "800083008310", 0x80, "Verschlüsselungs Schlüssel"}, + {1, 13, 1, "41015103", 0x83, "W2K Logon Schlüssel"}, + {3, 14, 1, "42015103", 0x83, "W2K Logon Schlüssel"}, + {3, 15, 1, "43015103", 0x83, "Schlüssel 1"}, + {3, 16, 1, "43015104", 0x84, "Schlüssel 2"}, + {0, 0, 0, NULL, 0, NULL} + }; + static const struct { + int type, id, auth_id, min_length; unsigned char reference; const char *path; const char *label; int flags; } pinlist[]={ - {1, 2, 6, 0x00, "5000", "globale PIN", + {0, 1, 2, 6, 0x00, "5000", "globale PIN", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN}, - {2, 0, 8, 0x01, "5001", "globale PUK", + {0, 2, 0, 8, 0x01, "5001", "globale PUK", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN}, - {3, 4, 6, 0x80, "DF015080", "lokale PIN0", + {1, 3, 4, 6, 0x80, "DF015080", "Netkey PIN0", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED}, - {4, 1, 6, 0x81, "DF015081", "lokale PIN1", + {1, 4, 1, 6, 0x81, "DF015081", "Netkey PIN1", SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN}, - {0, 0, 0, 0, NULL, NULL, 0} - }; - static const struct { - int id, auth_id; - const char *path; - unsigned char key_reference; - const char *label; - } keylist[]={ - {1, 4, "DF015331", 0x80, "Signatur-Schlüssel"}, - {2, 4, "DF015371", 0x82, "Authentifizierungs-Schlüssel"}, - {3, 3, "DF0153B1", 0x81, "Verschlüsselungs-Schlüssel"}, - {0, 0, NULL, 0, NULL} - }; - static const struct { - int id; - int writable; - const char *path; - const char *label; - } certlist[]={ - {1, 0, "DF01C000", "Telesec Signatur Zertifikat"}, - {1, 1, "DF014331", "User Signatur Zertifikat 1"}, - {1, 1, "DF014332", "User Signatur Zertifikat 2"}, - {2, 0, "DF01C100", "Telesec Authentifizierungs Zertifikat"}, - {2, 1, "DF014371", "User Authentifizierungs Zertifikat 1"}, - {2, 1, "DF014372", "User Authentifizierungs Zertifikat 2"}, - {3, 0, "DF01C200", "Telesec Verschlüsselungs Zertifikat"}, - {3, 1, "DF0143B1", "User Verschlüsselungs Zertifikat 1"}, - {3, 1, "DF0143B2", "User Verschlüsselungs Zertifikat 2"}, - {0, 0, NULL, NULL} + {2, 5, 1, 6, 0x81, "8000DF010000", "Signatur PIN", + SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | + SC_PKCS15_PIN_FLAG_INITIALIZED}, + {2, 6, 1, 6, 0x81, "800082000040", "Authentifizierungs PIN", + SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | + SC_PKCS15_PIN_FLAG_INITIALIZED}, + {2, 7, 1, 6, 0x81, "800083000040", "Verschlüsselungs PIN", + SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_LOCAL | + SC_PKCS15_PIN_FLAG_INITIALIZED}, + {0, 0, 0, 0, 0, NULL, NULL, 0} }; sc_card_t *card = p15card->card; sc_context_t *ctx = p15card->card->ctx; @@ -95,21 +121,13 @@ sc_pkcs15emu_netkey_init(sc_pkcs15_card_t *p15card) { sc_file_t *file; sc_serial_number_t serialnr; char serial[30]; - int i, r, usage; + int i, r, usage, cardtype; + /* check if we have the correct card OS unless SC_PKCS15EMU_FLAGS_NO_CHECK */ + i=(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK); + if (!i && strcmp(card->name, "TCOS")) return SC_ERROR_WRONG_CARD; - /* check if we have the correct card OS */ - if (strcmp(card->name, "TCOS")) return SC_ERROR_WRONG_CARD; - - /* check if we have a df01 DF with a C000 certificate */ - sc_format_path("3F00DF01C000", &path); - r = sc_select_file(card, &path, NULL); - if (r < 0) { - r = SC_ERROR_WRONG_CARD; - goto failed; - } - - /* get the card serial number */ + /* get the card serial number */ r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serialnr); if (r < 0) { sc_debug(ctx, "unable to get ICCSN\n"); @@ -119,98 +137,22 @@ sc_pkcs15emu_netkey_init(sc_pkcs15_card_t *p15card) { sc_bin_to_hex(serialnr.value, serialnr.len , serial, sizeof(serial), 0); serial[19] = '\0'; set_string(&p15card->serial_number, serial); - set_string(&p15card->label, "Netkey E4 Card"); - set_string(&p15card->manufacturer_id, "TeleSec"); - - for(i=0; pinlist[i].id; ++i){ - struct sc_pkcs15_pin_info pin_info; - struct sc_pkcs15_object pin_obj; - - if (ctx->debug >= 2) sc_debug(ctx, "Netkey: Loading %s: %s\n", pinlist[i].path, pinlist[i].label); - - sc_format_path(pinlist[i].path, &path); - r = sc_select_file(card, &path, &file); - if (r < 0) continue; - - memset(&pin_info, 0, sizeof(pin_info)); - pin_info.auth_id.len = 1; - pin_info.auth_id.value[0] = pinlist[i].id; - pin_info.reference = pinlist[i].reference; - pin_info.flags = pinlist[i].flags; - pin_info.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; - pin_info.min_length = pinlist[i].min_length; - pin_info.stored_length = 16; - pin_info.max_length = 16; - pin_info.pad_char = '\0'; - pin_info.tries_left = file->prop_attr[3]; - sc_format_path(pinlist[i].path, &pin_info.path); - - memset(&pin_obj, 0, sizeof(pin_obj)); - strncpy(pin_obj.label, pinlist[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); - pin_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE; - pin_obj.auth_id.len = pinlist[i].auth_id ? 0 : 1; - pin_obj.auth_id.value[0] = pinlist[i].auth_id; - - r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); - sc_file_free(file); - if (r < 0) { - sc_debug(ctx, "sc_pkcs15emu_add_pin_obj(%s) failed\n", pinlist[i].path); - r = SC_ERROR_INTERNAL; - goto failed; - } - } - - for(i=0; keylist[i].id; ++i){ - struct sc_pkcs15_prkey_info prkey_info; - struct sc_pkcs15_object prkey_obj; - - if (ctx->debug >= 2) sc_debug(ctx, "Netkey: Loading %s\n", keylist[i].label); - - sc_format_path(keylist[i].path, &path); - r = sc_select_file(card, &path, &file); - if (r < 0) continue; - - usage = SC_PKCS15_PRKEY_USAGE_SIGN; - if (file->prop_attr[1] & 0x04) - usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; - else if (file->prop_attr[1] & 0x08) - usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; - - memset(&prkey_info, 0, sizeof(prkey_info)); - prkey_info.id.len = 1; - prkey_info.id.value[0] = keylist[i].id; - prkey_info.usage = usage; - prkey_info.native = 1; - prkey_info.key_reference = keylist[i].key_reference; - prkey_info.modulus_length = 1024; - sc_format_path(keylist[i].path, &prkey_info.path); - - memset(&prkey_obj, 0, sizeof(prkey_obj)); - strncpy(prkey_obj.label, keylist[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); - prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; - prkey_obj.auth_id.len = 1; - prkey_obj.auth_id.value[0] = keylist[i].auth_id; - - r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); - sc_file_free(file); - if (r < 0) { - sc_debug(ctx, "sc_pkcs15emu_add_rsa_prkey(%s) failed\n", keylist[i].path); - r = SC_ERROR_INTERNAL; - goto failed; - } - } + cardtype=0; for(i=0; certlist[i].id; ++i){ struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; unsigned char cert[20]; - if (ctx->debug >= 2) sc_debug(ctx, "Netkey: Loading %s: %s\n", certlist[i].path, certlist[i].label); + if(certlist[i].type>0 && cardtype!=0 && cardtype!=certlist[i].type) continue; + if(certlist[i].type<0 && cardtype!=-certlist[i].type) continue; + sc_format_path(certlist[i].path, &path); card->ctx->suppress_errors++; r = sc_select_file(card, &path, NULL); card->ctx->suppress_errors--; if (r < 0) continue; + if(certlist[i].type>0) cardtype=certlist[i].type; /* read first 20 bytes of certificate, first two bytes * must be 0x30 0x82, otherwise this is an empty cert-file @@ -244,6 +186,93 @@ sc_pkcs15emu_netkey_init(sc_pkcs15_card_t *p15card) { goto failed; } } + if (ctx->debug >= 1) sc_debug(ctx, "Detected TCOS-Card Type-%d\n", cardtype); + if(cardtype<1 || cardtype>sizeof(cardlist)/sizeof(cardlist[0])){ + r = SC_ERROR_WRONG_CARD; + goto failed; + } + set_string(&p15card->label, cardlist[cardtype-1].card); + set_string(&p15card->manufacturer_id, cardlist[cardtype-1].manufacturer); + + for(i=0; keylist[i].id; ++i){ + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + + if(keylist[i].type!=cardtype) continue; + + sc_format_path(keylist[i].path, &path); + card->ctx->suppress_errors++; + r = sc_select_file(card, &path, &file); + card->ctx->suppress_errors--; + if (r < 0) continue; + + usage = SC_PKCS15_PRKEY_USAGE_SIGN; + if (file->prop_attr[1] & 0x04) usage |= SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; + if (file->prop_attr[1] & 0x08) usage |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; + + memset(&prkey_info, 0, sizeof(prkey_info)); + prkey_info.id.len = 1; + prkey_info.id.value[0] = keylist[i].id; + prkey_info.usage = usage; + prkey_info.native = 1; + prkey_info.key_reference = keylist[i].key_reference; + prkey_info.modulus_length = 1024; + sc_format_path(keylist[i].path, &prkey_info.path); + + memset(&prkey_obj, 0, sizeof(prkey_obj)); + strncpy(prkey_obj.label, keylist[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); + prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + prkey_obj.auth_id.len = 1; + prkey_obj.auth_id.value[0] = keylist[i].auth_id; + + r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + sc_file_free(file); + if (r < 0) { + sc_debug(ctx, "sc_pkcs15emu_add_rsa_prkey(%s) failed\n", keylist[i].path); + r = SC_ERROR_INTERNAL; + goto failed; + } + } + + for(i=0; pinlist[i].id; ++i){ + struct sc_pkcs15_pin_info pin_info; + struct sc_pkcs15_object pin_obj; + + if(pinlist[i].type && pinlist[i].type!=cardtype) continue; + + sc_format_path(pinlist[i].path, &path); + card->ctx->suppress_errors++; + r = sc_select_file(card, &path, &file); + card->ctx->suppress_errors--; + if (r < 0) continue; + + memset(&pin_info, 0, sizeof(pin_info)); + pin_info.auth_id.len = 1; + pin_info.auth_id.value[0] = pinlist[i].id; + pin_info.reference = pinlist[i].reference; + pin_info.flags = pinlist[i].flags; + pin_info.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; + pin_info.min_length = pinlist[i].min_length; + pin_info.stored_length = 16; + pin_info.max_length = 16; + pin_info.pad_char = '\0'; + pin_info.tries_left = file->prop_attr[3]; + sc_format_path(pinlist[i].path, &pin_info.path); + + memset(&pin_obj, 0, sizeof(pin_obj)); + strncpy(pin_obj.label, pinlist[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); + pin_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE; + pin_obj.auth_id.len = pinlist[i].auth_id ? 0 : 1; + pin_obj.auth_id.value[0] = pinlist[i].auth_id; + + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + sc_file_free(file); + if (r < 0) { + sc_debug(ctx, "sc_pkcs15emu_add_pin_obj(%s) failed\n", pinlist[i].path); + r = SC_ERROR_INTERNAL; + goto failed; + } + } /* return to MF */ sc_format_path("3F00", &path); @@ -251,36 +280,6 @@ sc_pkcs15emu_netkey_init(sc_pkcs15_card_t *p15card) { failed: if (r < 0) - sc_debug(card->ctx, "Failed to initialize TeleSec Netkey E4 emulation: %s\n", sc_strerror(r)); + sc_debug(card->ctx, "Failed to initialize TCOS based preformatted card: %s\n", sc_strerror(r)); return r; } - -static int netkey_detect_card(sc_pkcs15_card_t *p15card) -{ - int r; - sc_path_t path; - sc_card_t *card = p15card->card; - - /* check if we have the correct card OS */ - if (strcmp(card->name, "TCOS")) - return SC_ERROR_WRONG_CARD; - /* check if we have a df01 DF */ - sc_format_path("3F00DF01", &path); - r = sc_select_file(card, &path, NULL); - if (r < 0) - return SC_ERROR_WRONG_CARD; - return SC_SUCCESS; -} - -int sc_pkcs15emu_netkey_init_ex(sc_pkcs15_card_t *p15card, - sc_pkcs15emu_opt_t *opts) -{ - if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) - return sc_pkcs15emu_netkey_init(p15card); - else { - int r = netkey_detect_card(p15card); - if (r) - return SC_ERROR_WRONG_CARD; - return sc_pkcs15emu_netkey_init(p15card); - } -}