static int infocamere_1600_init(sc_pkcs15_card_t * p15card) { sc_card_t *card = p15card->card; sc_path_t path; sc_pkcs15_id_t id, auth_id; unsigned char serial[17]; int flags; int r; int hasAuthCert = 0; const char *certLabel[] = { "User Non-repudiation Certificate", "User Authentication Certificate" }; const char *certPath[] = { "200020010008", "20002001000E" }; const char *pinLabel[] = { "Non-repudiation PIN", "Authentication PIN" }; int retries[] = { 3, -1 }; const char *keyPath[] = { "200020010004", "20002001000A" }; const char *keyLabel[] = { "Non repudiation Key", "Authentication Key" }; static int usage[] = { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT }; auth_id.len = 1; id.len = 1; /* OpenSC doesn't define constants to identify BSOs for * restoring security environment, so we overload * the set_security_env function to support restore_sec_env */ set_security_env = card->ops->set_security_env; card->ops->set_security_env = infocamere_1400_set_sec_env; card->ops->compute_signature = do_sign; sc_format_path("200020012002", &path); r = sc_select_file(card, &path, NULL); if (r != SC_SUCCESS) return SC_ERROR_WRONG_CARD; sc_read_binary(card, 30, serial, 16, 0); serial[16] = '\0'; set_string(&p15card->serial_number, (char *) serial); set_string(&p15card->label, "Infocamere 1600 Card"); set_string(&p15card->manufacturer_id, "Infocamere"); /* Adding certificates. * Certificates are stored in a ZLib compressed form with * a 4 byte header, so we extract, decompress and cache * them. */ sc_format_path(certPath[0], &path); if (sc_select_file(card, &path, NULL) != SC_SUCCESS) return SC_ERROR_WRONG_CARD; id.value[0] = 1; sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, 0, &path, &id, certLabel[0], SC_PKCS15_CO_FLAG_MODIFIABLE); sc_format_path(certPath[1], &path); if (sc_select_file(card, &path, NULL) == SC_SUCCESS) { hasAuthCert = 1; id.value[0] = 2; sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, 1, &path, &id, certLabel[1], SC_PKCS15_CO_FLAG_MODIFIABLE); } flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_NEEDS_PADDING; /* adding PINs & private keys */ sc_format_path("2000", &path); id.value[0] = 1; sc_pkcs15emu_add_pin(p15card, &id, pinLabel[0], &path, 1, SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 5, 8, flags, retries[0], 0, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE); sc_format_path(keyPath[0], &path); auth_id.value[0] = 1; sc_pkcs15emu_add_prkey(p15card, &id, keyLabel[0], SC_PKCS15_TYPE_PRKEY_RSA, 1024, usage[0], &path, 1, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); if (hasAuthCert) { id.value[0] = 2; sc_pkcs15emu_add_pin(p15card, &id, pinLabel[1], &path, 2, SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 5, 8, flags, retries[1], 0, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE); sc_format_path(keyPath[1], &path); auth_id.value[0] = 2; sc_pkcs15emu_add_prkey(p15card, &id, keyLabel[1], SC_PKCS15_TYPE_PRKEY_RSA, 1024, usage[1], &path, 2, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); } /* return to MF */ sc_format_path("3F00", &path); r = sc_select_file(card, &path, NULL); return SC_SUCCESS; }
static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) { int r; unsigned int i; struct sc_path path; struct sc_file *file = NULL; struct sc_card *card = p15card->card; struct sc_apdu apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Setting pkcs15 parameters\n"); if (p15card->tokeninfo->label) free(p15card->tokeninfo->label); p15card->tokeninfo->label = malloc(strlen(APPLET_NAME) + 1); if (!p15card->tokeninfo->label) return SC_ERROR_INTERNAL; strcpy(p15card->tokeninfo->label, APPLET_NAME); if (p15card->tokeninfo->serial_number) free(p15card->tokeninfo->serial_number); p15card->tokeninfo->serial_number = malloc(strlen(DRIVER_SERIAL_NUMBER) + 1); if (!p15card->tokeninfo->serial_number) return SC_ERROR_INTERNAL; strcpy(p15card->tokeninfo->serial_number, DRIVER_SERIAL_NUMBER); /* the GemSAFE applet version number */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0xdf, 0x03); apdu.cla = 0x80; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); /* Manual says Le=0x05, but should be 0x08 to return full version numer */ apdu.le = 0x08; apdu.lc = 0; apdu.datalen = 0; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; /* the manufacturer ID, in this case GemPlus */ if (p15card->tokeninfo->manufacturer_id) free(p15card->tokeninfo->manufacturer_id); p15card->tokeninfo->manufacturer_id = malloc(strlen(MANU_ID) + 1); if (!p15card->tokeninfo->manufacturer_id) return SC_ERROR_INTERNAL; strcpy(p15card->tokeninfo->manufacturer_id, MANU_ID); /* determine allocated key containers and length of certificates */ r = gemsafe_get_cert_len(card); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; /* set certs */ sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Setting certificates\n"); for (i = 0; i < gemsafe_cert_max; i++) { struct sc_pkcs15_id p15Id; struct sc_path path; if (gemsafe_cert[i].label == NULL) continue; sc_format_path(gemsafe_cert[i].path, &path); sc_pkcs15_format_id(gemsafe_cert[i].id, &p15Id); path.index = gemsafe_cert[i].index; path.count = gemsafe_cert[i].count; sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, gemsafe_cert[i].authority, &path, &p15Id, gemsafe_cert[i].label, gemsafe_cert[i].obj_flags); } /* set gemsafe_pin */ sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Setting PIN\n"); for (i=0; i < gemsafe_pin_max; i++) { struct sc_pkcs15_id p15Id; struct sc_path path; sc_pkcs15_format_id(gemsafe_pin[i].id, &p15Id); sc_format_path(gemsafe_pin[i].path, &path); if (gemsafe_pin[i].atr_len == 0 || (gemsafe_pin[i].atr_len == p15card->card->atr.len && memcmp(p15card->card->atr.value, gemsafe_pin[i].atr, p15card->card->atr.len) == 0)) { sc_pkcs15emu_add_pin(p15card, &p15Id, gemsafe_pin[i].label, &path, gemsafe_pin[i].ref, gemsafe_pin[i].type, gemsafe_pin[i].minlen, gemsafe_pin[i].maxlen, gemsafe_pin[i].flags, gemsafe_pin[i].tries_left, gemsafe_pin[i].pad_char, gemsafe_pin[i].obj_flags); break; } }; /* set private keys */ sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Setting private keys\n"); for (i = 0; i < gemsafe_cert_max; i++) { struct sc_pkcs15_id p15Id, authId, *pauthId; struct sc_path path; int key_ref = 0x03; if (gemsafe_prkeys[i].label == NULL) continue; sc_pkcs15_format_id(gemsafe_prkeys[i].id, &p15Id); if (gemsafe_prkeys[i].auth_id) { sc_pkcs15_format_id(gemsafe_prkeys[i].auth_id, &authId); pauthId = &authId; } else pauthId = NULL; sc_format_path(gemsafe_prkeys[i].path, &path); /* * The key ref may be different for different sites; * by adding flags=n where the low order 4 bits can be * the key ref we can force it. */ if ( p15card->card->flags & 0x0F) { key_ref = p15card->card->flags & 0x0F; sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Overriding key_ref %d with %d\n", gemsafe_prkeys[i].ref, key_ref); } else key_ref = gemsafe_prkeys[i].ref; sc_pkcs15emu_add_prkey(p15card, &p15Id, gemsafe_prkeys[i].label, SC_PKCS15_TYPE_PRKEY_RSA, gemsafe_prkeys[i].modulus_len, gemsafe_prkeys[i].usage, &path, key_ref, pauthId, gemsafe_prkeys[i].obj_flags); } /* select the application DF */ sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,"Selecting application DF\n"); sc_format_path(GEMSAFE_APP_PATH, &path); r = sc_select_file(card, &path, &file); if (r != SC_SUCCESS || !file) return SC_ERROR_INTERNAL; /* set the application DF */ if (p15card->file_app) free(p15card->file_app); p15card->file_app = file; return SC_SUCCESS; }
static int sc_pkcs15emu_postecert_init(sc_pkcs15_card_t * p15card) { static int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; static int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER | SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_DECRYPT; sc_card_t *card = p15card->card; sc_path_t path; sc_pkcs15_id_t id, auth_id; unsigned char certlen[2]; unsigned char *certi = NULL; int index_cert[4]; int count_cert[4]; int flags; int authority; size_t i, count; int r; int o = 0; const char *label = "User Non-repudiation Certificate"; const char *calabel = "CA Certificate"; const char *catmslabel = "CA TimeStamper Certificate"; const char *authlabel = "User Authentication Certificate"; const char *postecert_auth_cert_path = "504B0001"; const char *authPIN = "Authentication PIN"; const char *nonrepPIN = "Non-repudiation PIN"; const char *authPRKEY = "Authentication Key"; const char *nonrepPRKEY = "Non repudiation Key"; /* Get the non-repudiation certificate length */ sc_format_path(postecert_auth_cert_path, &path); if (sc_select_file(card, &path, NULL) < 0) { r = SC_ERROR_WRONG_CARD; goto failed; } set_string(&p15card->label, "Postecert & Cnipa Card"); set_string(&p15card->manufacturer_id, "Postecert"); set_string(&p15card->serial_number, "0000"); sc_read_binary(card, 0, certlen, 2, 0); /* Now set the certificate offset/len */ count = (certlen[0] << 8) + certlen[1]; if (count < 256) return SC_ERROR_INTERNAL; certi = (unsigned char *) malloc(count); if (!certi) return SC_ERROR_OUT_OF_MEMORY; sc_read_binary(card, 0, certi, count - 500, 0); for (i = 2; i < (count - 256); i++) { /* this file contain more than one certificate */ if (*(certi + i) == 0x30 && *(certi + i + 1) == 0x82 && *(certi + i + 4) == 0x30 && *(certi + i + 5) == 0x82 && *(certi + i + 2) > 1 && *(certi + i + 2) < 8 && *(certi + i + 6) <= *(certi + i + 2)) { index_cert[o] = i; count_cert[o] = (*(certi + i + 2) << 8) + *(certi + i + 3) + 4; o++; if (o > 4) break; i += (*(certi + i + 2) << 8) + *(certi + i + 3); } } free(certi); path.index = index_cert[0]; path.count = count_cert[0]; id.value[0] = 1; id.len = 1; authority = 1; sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, authority, &path, &id, calabel, SC_PKCS15_CO_FLAG_MODIFIABLE); path.index = index_cert[1]; path.count = count_cert[1]; id.value[0] = 2; id.len = 1; authority = 1; sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, authority, &path, &id, catmslabel, SC_PKCS15_CO_FLAG_MODIFIABLE); path.index = index_cert[2]; path.count = count_cert[2]; id.value[0] = 3; id.len = 1; authority = 0; sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, authority, &path, &id, label, SC_PKCS15_CO_FLAG_MODIFIABLE); path.index = index_cert[3]; path.count = count_cert[3]; id.value[0] = 4; id.len = 1; sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, authority, &path, &id, authlabel, SC_PKCS15_CO_FLAG_MODIFIABLE); flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE | SC_PKCS15_PIN_FLAG_INITIALIZED | SC_PKCS15_PIN_FLAG_NEEDS_PADDING; /* add authentication PIN */ sc_format_path("3F00504B", &path); id.value[0] = 1; sc_pkcs15emu_add_pin(p15card, &id, authPIN, &path, 0x82, SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 6, 14, flags, 3, 0, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE); /* add authentication private key */ id.value[0] = 4; auth_id.value[0] = 1; auth_id.len = 1; sc_pkcs15emu_add_prkey(p15card, &id, authPRKEY, SC_PKCS15_TYPE_PRKEY_RSA, 1024, authprkey_usage, &path, 0x06, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); /* add non repudiation PIN */ sc_format_path("3F00504B", &path); id.value[0] = 2; sc_pkcs15emu_add_pin(p15card, &id, nonrepPIN, &path, 0x82, SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 6, 14, flags, 3, 0, SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE); /* add non repudiation private key */ id.value[0] = 3; auth_id.value[0] = 2; sc_pkcs15emu_add_prkey(p15card, &id, nonrepPRKEY, SC_PKCS15_TYPE_PRKEY_RSA, 1024, prkey_usage, &path, 0x01, &auth_id, SC_PKCS15_CO_FLAG_PRIVATE); /* return to MF */ sc_format_path("3F00", &path); r = sc_select_file(card, &path, NULL); if (r != SC_SUCCESS) return r; { /* save old signature funcs */ set_security_env = card->ops->set_security_env; /* set new one */ card->ops->set_security_env = set_sec_env; card->ops->compute_signature = do_sign; } return 0; failed: sc_error(card->ctx, "Failed to initialize Postecert and Cnipa emulation: %s\n", sc_strerror(r)); return r; }
static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card) { const char *fn_name = "sc_pkcs15emu_gemsafe_init"; int r, i; int key_ref = 0x03; struct sc_path path; struct sc_file *file = NULL; struct sc_card *card = p15card->card; struct sc_apdu apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; char * endptr; float version=0.0; sc_debug(p15card->card->ctx, "%s: Setting pkcs15 parameters\n", fn_name); if (p15card->label) free(p15card->label); p15card->label = malloc(strlen(APPLET_NAME) + 1); if (!p15card->label) return SC_ERROR_INTERNAL; strcpy(p15card->label, APPLET_NAME); if (p15card->serial_number) free(p15card->serial_number); p15card->serial_number = malloc(strlen(DRIVER_SERIAL_NUMBER) + 1); if (!p15card->serial_number) return SC_ERROR_INTERNAL; strcpy(p15card->serial_number, DRIVER_SERIAL_NUMBER); /* the GemSAFE applet version number */ sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0xdf, 0x03); apdu.cla = 0x80; apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); /* Manual says Le=0x05, but should be 0x08 to return full version numer */ apdu.le = 0x08; apdu.lc = 0; apdu.datalen = 0; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) return SC_ERROR_INTERNAL; if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; endptr = (char *)(apdu.resp + apdu.resplen); version = strtod( (const char *)(apdu.resp + 4), &endptr); sc_debug(p15card->card->ctx, "%s: version (float): %f, version (int): %d\n", fn_name, version, (int)version); p15card->version = (int)version; /* the manufacturer ID, in this case GemPlus */ if (p15card->manufacturer_id) free(p15card->manufacturer_id); p15card->manufacturer_id = malloc(strlen(MANU_ID) + 1); if (!p15card->manufacturer_id) return SC_ERROR_INTERNAL; strcpy(p15card->manufacturer_id, MANU_ID); /* set certs */ sc_debug(p15card->card->ctx, "%s: Setting certificate\n", fn_name); for (i = 0; gemsafe_cert[i].label; i++) { struct sc_pkcs15_id p15Id; sc_format_path(gemsafe_cert[i].path, &path); if (!gemsafe_get_cert_len(card, &path, &key_ref)) /* skip errors */ continue; sc_pkcs15_format_id(gemsafe_cert[i].id, &p15Id); sc_pkcs15emu_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, gemsafe_cert[i].authority, &path, &p15Id, gemsafe_cert[i].label, gemsafe_cert[i].obj_flags); } /* set gemsafe_pin */ sc_debug(p15card->card->ctx, "%s: Setting PIN\n", fn_name); for (i = 0; gemsafe_pin[i].label; i++) { struct sc_pkcs15_id p15Id; sc_pkcs15_format_id(gemsafe_pin[i].id, &p15Id); sc_pkcs15emu_add_pin(p15card, &p15Id, gemsafe_pin[i].label, &path, gemsafe_pin[i].ref, gemsafe_pin[i].type, gemsafe_pin[i].minlen, gemsafe_pin[i].maxlen, gemsafe_pin[i].flags, gemsafe_pin[i].tries_left, gemsafe_pin[i].pad_char, gemsafe_pin[i].obj_flags); } /* set private keys */ sc_debug(p15card->card->ctx, "%s: Setting private key\n", fn_name); for (i = 0; gemsafe_prkeys[i].label; i++) { struct sc_pkcs15_id p15Id, authId, *pauthId; sc_pkcs15_format_id(gemsafe_prkeys[i].id, &p15Id); if (gemsafe_prkeys[i].auth_id) { sc_pkcs15_format_id(gemsafe_prkeys[i].auth_id, &authId); pauthId = &authId; } else pauthId = NULL; /* * the key ref may be different for different sites * by adding flags=n where the low order 4 bits can be * the key ref we can force it. */ if ( p15card->card->flags & 0x0F) { key_ref = p15card->card->flags & 0x0F; sc_debug(p15card->card->ctx, "Overriding key_ref with %d\n", key_ref); } sc_pkcs15emu_add_prkey(p15card, &p15Id, gemsafe_prkeys[i].label, SC_PKCS15_TYPE_PRKEY_RSA, gemsafe_prkeys[i].modulus_len, gemsafe_prkeys[i].usage, &path, key_ref, pauthId, gemsafe_prkeys[i].obj_flags); } /* select the application DF */ sc_debug(p15card->card->ctx,"%s: Selecting application DF\n", fn_name); sc_format_path("3F001600", &path); r = sc_select_file(card, &path, &file); if (r != SC_SUCCESS || !file) return SC_ERROR_INTERNAL; /* set the application DF */ if (p15card->file_app) free(p15card->file_app); p15card->file_app = file; return SC_SUCCESS; }