From d3201511c7efc5d30c9105a1c92dac63f4af4808 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 12 Sep 2009 11:46:00 +0000 Subject: [PATCH 02/57] r3717:3719 from trunk git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3720 c6295689-39f2-0310-b995-f0e70906c6a9 --- NEWS | 3 + doc/tools/tools.xml | 1 + doc/tools/westcos-tool.xml | 140 ++++ src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 2 + src/libopensc/card-westcos.c | 1355 +++++++++++++++++++++++++++++++ src/libopensc/cardctl.h | 29 + src/libopensc/cards.h | 1 + src/libopensc/ctx.c | 1 + src/libopensc/p15emu-westcos.c | 251 ++++++ src/libopensc/pkcs15-syn.c | 3 + src/pkcs15init/Makefile.am | 4 +- src/pkcs15init/Makefile.mak | 2 +- src/pkcs15init/pkcs15-init.h | 1 + src/pkcs15init/pkcs15-lib.c | 1 + src/pkcs15init/pkcs15-westcos.c | 464 +++++++++++ src/pkcs15init/westcos.profile | 183 +++++ src/tools/Makefile.am | 5 +- src/tools/Makefile.mak | 2 +- src/tools/westcos-tool.c | 942 +++++++++++++++++++++ 20 files changed, 3388 insertions(+), 6 deletions(-) create mode 100644 doc/tools/westcos-tool.xml create mode 100644 src/libopensc/card-westcos.c create mode 100644 src/libopensc/p15emu-westcos.c create mode 100644 src/pkcs15init/pkcs15-westcos.c create mode 100644 src/pkcs15init/westcos.profile create mode 100644 src/tools/westcos-tool.c diff --git a/NEWS b/NEWS index b1cb579e..36bf26f4 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,9 @@ http://www.opensc-project.org/opensc/wiki/WhatsNew Also see the svn changelog using svn command or doc/nonpersistent/ChangeLog. +New in 0.??.==; 200?-??-??; ?? +* New westcos driver by François Leblanc + New in 0.11.9; 2009-07-29; Andreas Jellinghaus * New rutoken_ecp driver by Aktiv Co. / Aleksey Samsonov * Allow more keys/certificates/files etc. with entersafe tokens diff --git a/doc/tools/tools.xml b/doc/tools/tools.xml index c1246010..6bdc675e 100644 --- a/doc/tools/tools.xml +++ b/doc/tools/tools.xml @@ -19,6 +19,7 @@ + diff --git a/doc/tools/westcos-tool.xml b/doc/tools/westcos-tool.xml new file mode 100644 index 00000000..fc2cc278 --- /dev/null +++ b/doc/tools/westcos-tool.xml @@ -0,0 +1,140 @@ + + + + westcos-tool + 1 + opensc + + + + westcos-tool + utility for manipulating data structure + on westcos smart card and similar security tokens + + + + Synopsis + + westcos-tool [OPTIONS] + + + + + Description + + The westcos-tool utility is used to manipulate + the westcos data structures on 2 Ko smart cards. Users can create PINs, + keys and certificates stored on the token. User PIN authentication is + performed for those operations that require it. + + + + + Options + + + + + Generate a private key on smart card. The smart card must be + not finalized and pin installed (ig. file for pin must be created, see option + -i). By default key length is 1536 bits. User authentication is required for + this operation. + + + + length + Change the length of private key, use with . + + + + + + Install pin file in token, you must provide pin value + with . + + + + value + set value of pin. + + + + value + set value of puk (or value of new pin for change pin + command see ). + + + + + Changes a PIN stored on the token. User authentication + is required for this operation. + + + + + Unblocks a PIN stored on the token. Knowledge of the Pin + Unblock Key (PUK) is required for this operation. + + + + file + Write certificate file in pem format on the + card. User authentication is required for this operation. + + + + + Finalize the card, once finalize default key is invalidate so pin and puk + can'be changed anymore without user authentification. Warning, smart cards not finalized are + unsecure because pin can be changed without user authentification (knowledge of default key + is enougth). + + + + n + Forces westcos-tool to use reader + number n for operations. + + + + path + Get the file path the file is written + on disk with path name. User authentication + is required for this operation. + + + + path + Put the file with name path from disk + to card the file is written in path. User authentication + is required for this operation. + + + + + Causes westcos-tool to be more + verbose. Specify this flag several times to enable debug output + in the OpenSC library. + + + + + Print help message on screen. + + + + + + + + See also + opensc(7) + + + + Authors + westcos-tool was written by + Francois Leblanc francois.leblanc@cev-sa.com. + + + diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 16b4f67f..ae3542b9 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -40,12 +40,12 @@ libopensc_la_SOURCES = \ card-oberthur.c card-belpic.c card-atrust-acos.c card-entersafe.c \ card-incrypto34.c card-piv.c card-muscle.c card-acos5.c \ card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ - card-rtecp.c \ + card-rtecp.c card-westcos.c \ \ pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \ pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ - pkcs15-esinit.c \ + pkcs15-esinit.c p15emu-westcos.c \ compression.c p15card-helper.c \ \ libopensc.exports diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 5acccce6..a06fa827 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -22,6 +22,7 @@ OBJECTS = \ \ ctbcs.obj reader-ctapi.obj reader-pcsc.obj reader-openct.obj \ \ + card-westcos.obj crc_AetB.obj \ card-setcos.obj card-miocos.obj card-flex.obj card-gpk.obj \ card-cardos.obj card-tcos.obj card-emv.obj card-default.obj \ card-mcrd.obj card-starcos.obj card-openpgp.obj card-jcop.obj \ @@ -30,6 +31,7 @@ OBJECTS = \ card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \ card-rtecp.obj \ \ + p15emu-westcos.obj \ pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \ pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \ pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c new file mode 100644 index 00000000..77091dc1 --- /dev/null +++ b/src/libopensc/card-westcos.c @@ -0,0 +1,1355 @@ +/* + * card-westcos.c: support for westcos card + * + * Copyright (C) 2009 francois.leblanc@cev-sa.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "internal.h" +#include +#include +#include +#include +#include "cardctl.h" +#include "asn1.h" + +#ifdef ENABLE_OPENSSL +#include +#include +#include +#include +#include +#include +#endif + +#ifndef min +#define min(a,b) (((a)<(b))?(a):(b)) +#endif + +#ifndef min +#define max(a,b) (((a)>(b))?(a):(b)) +#endif + +#define DEFAULT_TRANSPORT_KEY "6f:59:b0:ed:6e:62:46:4a:5d:25:37:68:23:a8:a2:2d" + +#define JAVACARD (0x01) + +#ifdef ENABLE_OPENSSL +#define DEBUG_SSL +#ifdef DEBUG_SSL +static void print_openssl_erreur(void) +{ + static int charge = 0; + long r; + + if (!charge) { + ERR_load_crypto_strings(); + charge = 1; + } + while ((r = ERR_get_error()) != 0) + fprintf(stderr, "%s\n", ERR_error_string(r, NULL)); +} +#endif +#endif + +typedef struct { + sc_security_env_t env; + sc_autkey_t default_key; + int flags; + int file_id; +} priv_data_t; + +static const struct sc_card_operations *iso_ops = NULL; +static struct sc_card_operations westcos_ops; + +static struct sc_card_driver westcos_drv = { + "WESTCOS compatible cards", "westcos", &westcos_ops, NULL, 0, NULL +}; + +static int westcos_get_default_key(sc_card_t * card, + struct sc_cardctl_default_key *data) +{ + const char *default_key; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, + "westcos_get_default_key:data->method=%d, data->key_ref=%d\n", + data->method, data->key_ref); + if (data->method != SC_AC_AUT || data->key_ref != 0) + return SC_ERROR_NO_DEFAULT_KEY; + default_key = + scconf_get_str(card->ctx->conf_blocks[0], "westcos_default_key", + DEFAULT_TRANSPORT_KEY); + return sc_hex_to_bin(default_key, data->key_data, &data->len); +} + +#define CRC_A 1 +#define CRC_B 2 + +static unsigned short westcos_update_crc(unsigned char ch, unsigned short *lpwCrc) +{ + ch = (ch ^ (unsigned char)((*lpwCrc) & 0x00FF)); + ch = (ch ^ (ch << 4)); + *lpwCrc = + (*lpwCrc >> 8) ^ ((unsigned short)ch << 8) ^ ((unsigned short)ch << + 3) ^ ((unsigned short) + ch >> 4); + return (*lpwCrc); +} + +static void westcos_compute_aetb_crc(int CRCType, + unsigned char *Data, + size_t Length, + unsigned char * TransmitFirst, + unsigned char * TransmitSecond) +{ + unsigned char chBlock; + unsigned short wCrc; + switch (CRCType) { + case CRC_A: + wCrc = 0x6363; // ITU-V.41 + break; + case CRC_B: + wCrc = 0xFFFF; // ISO 3309 + break; + default: + return; + } + + do { + chBlock = *Data++; + westcos_update_crc(chBlock, &wCrc); + } while (--Length); + if (CRCType == CRC_B) + wCrc = ~wCrc; // ISO 3309 + *TransmitFirst = (unsigned char) (wCrc & 0xFF); + *TransmitSecond = (unsigned char) ((wCrc >> 8) & 0xFF); + return; +} + +static int westcos_check_sw(sc_card_t * card, unsigned int sw1, + unsigned int sw2) +{ + if ((sw1 == 0x69) && (sw2 == 0x88)) + return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; + assert(iso_ops && iso_ops->check_sw); + return iso_ops->check_sw(card, sw1, sw2); +} + +typedef struct mon_atr { + size_t len; + int flags; + u8 *atr, *mask; +} mon_atr_t; + +static mon_atr_t atrs[] = { + {13, 0x00, + "\x3f\x69\x00\x00\x00\x64\x01\x00\x00\x00\x80\x90\x00", + "\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\xf0\xff\xff"}, + {12, JAVACARD, + "\x3b\x95\x94\x80\x1F\xC3\x80\x73\xC8\x21\x13\x54", + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"} +}; + +static int westcos_finish(sc_card_t * card) +{ + if (card->algorithms) + free(card->algorithms); + card->algorithms = NULL; + card->algorithm_count = 0; + if (card->drv_data) + free(card->drv_data); + return 0; +} + +static int westcos_match_card(sc_card_t * card) +{ + u8 *p, j; + size_t i; + mon_atr_t *matr; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_match_card %d, %X:%X:%X\n", + card->atr_len, card->atr[0], card->atr[1], + card->atr[2]); + for (i = 0; i < sizeof(atrs) / sizeof(*atrs); i++) { + matr = &atrs[i]; + if (matr->len != card->atr_len) + continue; + p = card->atr; + for (j = 0; j < card->atr_len; j++) { + if (((matr->mask[j]) & (*p)) != (matr->atr[j])) + break; + p++; + if (*p == ':') + p++; + } + if (j >= card->atr_len) { + if (matr->flags & JAVACARD) { + int r; + sc_apdu_t apdu; + u8 aid[] = { + 0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01 + }; + sc_format_apdu(card, &apdu, + SC_APDU_CASE_3_SHORT, 0xA4, 0x04, + 0); + apdu.cla = 0x00; + apdu.lc = sizeof(aid); + apdu.datalen = sizeof(aid); + apdu.data = aid; + sc_ctx_suppress_errors_on(card->ctx); + r = sc_transmit_apdu(card, &apdu); + sc_ctx_suppress_errors_off(card->ctx); + if (r) + continue; + sc_ctx_suppress_errors_on(card->ctx); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + sc_ctx_suppress_errors_off(card->ctx); + if (r) + continue; + } + card->drv_data = malloc(sizeof(priv_data_t)); + if (card->drv_data == NULL) + return SC_ERROR_OUT_OF_MEMORY; + memset(card->drv_data, 0, sizeof(card->drv_data)); + if (matr->flags & JAVACARD) { + priv_data_t *priv_data = + (priv_data_t *) card->drv_data; + priv_data->flags |= JAVACARD; + } + return 1; + } + } + return 0; +} + +static int westcos_init(sc_card_t * card) +{ + int r; + const char *default_key; + unsigned long exponent, flags; + if (card == NULL || card->drv_data == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + card->cla = 0x00; + card->max_send_size = 240; + card->max_recv_size = 240; + exponent = 0; + flags = SC_ALGORITHM_RSA_RAW; + flags |= SC_ALGORITHM_RSA_HASH_NONE; + flags |= SC_ALGORITHM_RSA_PAD_NONE | SC_ALGORITHM_RSA_PAD_PKCS1; + flags |= SC_ALGORITHM_ONBOARD_KEY_GEN; + _sc_card_add_rsa_alg(card, 128, flags, exponent); + _sc_card_add_rsa_alg(card, 256, flags, exponent); + _sc_card_add_rsa_alg(card, 512, flags, exponent); + _sc_card_add_rsa_alg(card, 768, flags, exponent); + _sc_card_add_rsa_alg(card, 1024, flags, exponent); + _sc_card_add_rsa_alg(card, 1100, flags, exponent); + _sc_card_add_rsa_alg(card, 1200, flags, exponent); + _sc_card_add_rsa_alg(card, 1300, flags, exponent); + _sc_card_add_rsa_alg(card, 1400, flags, exponent); + _sc_card_add_rsa_alg(card, 1536, flags, exponent); + _sc_card_add_rsa_alg(card, 2048, flags, exponent); + default_key = + scconf_get_str(card->ctx->conf_blocks[0], "westcos_default_key", + DEFAULT_TRANSPORT_KEY); + if (default_key) { + priv_data_t *priv_data = (priv_data_t *) (card->drv_data); + priv_data->default_key.key_reference = 0; + priv_data->default_key.key_len = + sizeof(priv_data->default_key.key_value); + r = sc_hex_to_bin(default_key, priv_data->default_key.key_value, + &(priv_data->default_key.key_len)); + if (r) + return (r); + } + return 0; +} + +static int westcos_select_file(sc_card_t * card, const sc_path_t * in_path, + sc_file_t ** file_out) +{ + sc_context_t *ctx; + sc_apdu_t apdu; + u8 buf[SC_MAX_APDU_BUFFER_SIZE]; + u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; + int r, pathlen; + sc_file_t *file = NULL; + priv_data_t *priv_data = NULL; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_select_file\n"); + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + priv_data = (priv_data_t *) card->drv_data; + priv_data->file_id = 0; + ctx = card->ctx; + memcpy(path, in_path->value, in_path->len); + pathlen = (int)in_path->len; + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0); + switch (in_path->type) { + case SC_PATH_TYPE_FILE_ID: + apdu.p1 = 0; + if (pathlen != 2) + return SC_ERROR_INVALID_ARGUMENTS; + break; + case SC_PATH_TYPE_DF_NAME: + apdu.p1 = 4; + break; + case SC_PATH_TYPE_PATH: + apdu.p1 = 9; + if (pathlen == 2 && memcmp(path, "\x3F\x00", 2) == 0) { + apdu.p1 = 0; + } + + else if (pathlen > 2 && memcmp(path, "\x3F\x00", 2) == 0) { + apdu.p1 = 8; + pathlen -= 2; + memcpy(path, &in_path->value[2], pathlen); + } + break; + case SC_PATH_TYPE_FROM_CURRENT: + apdu.p1 = 9; + break; + case SC_PATH_TYPE_PARENT: + apdu.p1 = 3; + pathlen = 0; + apdu.cse = SC_APDU_CASE_3_SHORT; + break; + default: + return SC_ERROR_INVALID_ARGUMENTS; + } + apdu.p2 = 0; /* first record, return FCI */ + apdu.lc = pathlen; + apdu.data = path; + apdu.datalen = pathlen; + if (file_out != NULL) { + apdu.resp = buf; + apdu.resplen = sizeof(buf); + apdu.le = 255; + } else { + apdu.resplen = 0; + apdu.le = 0; + apdu.cse = SC_APDU_CASE_3_SHORT; + } + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + if (file_out == NULL) { + if (apdu.sw1 == 0x61) + return 0; + return sc_check_sw(card, apdu.sw1, apdu.sw2); + } + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return (r); + switch (apdu.resp[0]) { + case 0x6F: + file = sc_file_new(); + if (file == NULL) + return SC_ERROR_OUT_OF_MEMORY; + file->path = *in_path; + if (card->ops->process_fci == NULL) { + sc_file_free(file); + return SC_ERROR_NOT_SUPPORTED; + } + if (apdu.resp[1] <= apdu.resplen) + card->ops->process_fci(card, file, apdu.resp + 2, + apdu.resp[1]); + *file_out = file; + break; + case 0x00: /* proprietary coding */ + return SC_ERROR_UNKNOWN_DATA_RECEIVED; + default: + return SC_ERROR_UNKNOWN_DATA_RECEIVED; + } + return 0; +} + +static int _westcos2opensc_ac(u8 flag) +{ + if (flag == 0) + return SC_AC_NEVER; + else if (flag == 1) + return SC_AC_CHV; + else if (flag == 2) + return SC_AC_AUT; + else if (flag == 15) + return SC_AC_NONE; + return SC_AC_UNKNOWN; +} + +static int westcos_process_fci(sc_card_t * card, sc_file_t * file, + const u8 * buf, size_t buflen) +{ + sc_context_t *ctx = card->ctx; + size_t taglen, len = buflen; + const u8 *tag = NULL, *p = buf; + if (card->ctx->debug >= 5) + sc_debug(card->ctx, "processing FCI bytes\n"); + tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen); + if (tag != NULL && taglen == 2) { + file->id = (tag[0] << 8) | tag[1]; + if (card->ctx->debug >= 5) + sc_debug(card->ctx, " file identifier: 0x%02X%02X\n", + tag[0], tag[1]); + } + tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen); + if (tag != NULL && taglen >= 2) { + int bytes = (tag[0] << 8) + tag[1]; + if (card->ctx->debug >= 5) + sc_debug(card->ctx, " bytes in file: %d\n", bytes); + file->size = bytes; + } + if (tag == NULL) { + tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen); + if (tag != NULL && taglen >= 2) { + int bytes = (tag[0] << 8) + tag[1]; + if (card->ctx->debug >= 5) + sc_debug(card->ctx, " bytes in file: %d\n", + bytes); + file->size = bytes; + } + } + tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen); + if (tag != NULL) { + if (taglen > 0) { + unsigned char byte = tag[0]; + const char *type; + file->shareable = 0; + if (card->ctx->debug >= 5) + sc_debug(card->ctx, " shareable: %s\n", + (file->shareable) ? "yes" : "no"); + file->ef_structure = SC_FILE_EF_UNKNOWN; + switch (byte) { + case 0x38: + type = "DF"; + file->type = SC_FILE_TYPE_DF; + break; + case 0x01: + type = "working or internal EF"; + file->type = SC_FILE_TYPE_WORKING_EF; + file->ef_structure = SC_FILE_EF_TRANSPARENT; + break; + case 0x02: + type = "working or internal EF"; + file->type = SC_FILE_TYPE_WORKING_EF; + file->ef_structure = SC_FILE_EF_LINEAR_FIXED; + break; + case 0x06: + type = "working or internal EF"; + file->type = SC_FILE_TYPE_WORKING_EF; + file->ef_structure = SC_FILE_EF_CYCLIC; + break; + default: + type = "unknow"; + } + if (card->ctx->debug >= 5) + sc_debug(card->ctx, " type: %s\n", type); + if (card->ctx->debug >= 5) + sc_debug(card->ctx, " EF structure: %d\n", + file->ef_structure); + } + } + tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen); + if (tag != NULL && taglen > 0 && taglen <= 16) { + memcpy(file->name, tag, taglen); + file->namelen = taglen; + if (card->ctx->debug >= 5) { + char tbuf[128]; + sc_hex_dump(ctx, file->name, file->namelen, tbuf, + sizeof(tbuf)); + sc_debug(card->ctx, " File name: %s\n", tbuf); + } + } + if (file->type == SC_FILE_TYPE_DF) { + tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen); + if (tag != NULL && taglen == 3) { + file->size = tag[1] * 256 + tag[2]; + } else + file->size = 0; + } + tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen); + if (tag != NULL && taglen) { + sc_file_set_prop_attr(file, tag, taglen); + } + tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen); + if (tag != NULL && taglen) { + sc_file_set_sec_attr(file, tag, taglen); + + /* FIXME: compact file system only */ + if (file->type == SC_FILE_TYPE_DF) { + sc_file_add_acl_entry(file, SC_AC_OP_SELECT, + _westcos2opensc_ac(tag[0] >> + 4), + tag[0 + 4] >> 4); + sc_file_add_acl_entry(file, SC_AC_OP_CREATE, + _westcos2opensc_ac(tag[0] & + 0x0f), + tag[0 + 4] & 0x0f); + sc_file_add_acl_entry(file, SC_AC_OP_INVALIDATE, + _westcos2opensc_ac(tag[1] >> + 4), + tag[1 + 4] >> 4); + } + + else { + if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { + sc_file_add_acl_entry(file, SC_AC_OP_READ, + _westcos2opensc_ac(tag[0] + >> + 4), + tag[0 + 4] >> 4); + sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, + _westcos2opensc_ac(tag[0] + & + 0x0f), + tag[0 + 4] & 0x0f); + sc_file_add_acl_entry(file, + SC_AC_OP_INVALIDATE, + _westcos2opensc_ac(tag[1] + >> + 4), + tag[1 + 4] >> 4); + sc_file_add_acl_entry(file, SC_AC_OP_ERASE, + _westcos2opensc_ac(tag[1] + & + 0x0f), + tag[1 + 4] & 0x0f); + } + + else { + sc_file_add_acl_entry(file, SC_AC_OP_READ, + _westcos2opensc_ac(tag[0] + >> + 4), + tag[0 + 4] >> 4); + sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, + _westcos2opensc_ac(tag[0] + & + 0x0f), + tag[0 + 4] & 0x0f); + sc_file_add_acl_entry(file, + SC_AC_OP_INVALIDATE, + _westcos2opensc_ac(tag[1] + >> + 4), + tag[1 + 4] >> 4); + } + } + } + return 0; +} + +#define HIGH (0) +#define LOW (1) +static int _convertion_ac_methode(sc_file_t * file, int low, + unsigned int operation, u8 * buf, + u8 * buf_key) +{ + const struct sc_acl_entry *acl; + acl = sc_file_get_acl_entry(file, operation); + if (acl == NULL) { + + /* par defaut always */ + *buf = 0xff; + *buf_key = 0x00; + return 0; + } + switch (acl->method) { + case SC_AC_NONE: + if (low) + *buf |= 0x0f; + + else + *buf |= 0xf0; + break; + case SC_AC_CHV: /* Card Holder Verif. */ + if (low) + *buf |= 0x01; + + else + *buf |= 0x10; + break; + case SC_AC_TERM: /* Terminal auth. */ + return SC_ERROR_NOT_SUPPORTED; + case SC_AC_PRO: /* Secure Messaging */ + return SC_ERROR_NOT_SUPPORTED; + case SC_AC_AUT: /* Key auth. */ + if (low) + *buf |= 0x02; + + else + *buf |= 0x20; + if (acl->key_ref > 15) + return SC_ERROR_NOT_SUPPORTED; + if (low) + *buf_key |= acl->key_ref; + + else + *buf_key |= (acl->key_ref) << 4; + break; + case SC_AC_NEVER: + *buf |= 0; + break; + default: + return SC_ERROR_NOT_SUPPORTED; + } + return 0; +} + +static int westcos_create_file(sc_card_t *card, struct sc_file *file) +{ + int r; + sc_apdu_t apdu; + u8 buf[12], p1 = 0, p2 = 0; + int buflen; + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_create_file\n"); + memset(buf, 0, sizeof(buf)); + + /* clef de transport */ + r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL); + if (r) + return (r); + buflen = sizeof(buf); + switch (file->type) { + case SC_FILE_TYPE_DF: + buf[0] = 0x00; + buf[1] = 0x01; + _convertion_ac_methode(file, HIGH, SC_AC_OP_SELECT, &buf[2], + &buf[2 + 4]); + _convertion_ac_methode(file, LOW, SC_AC_OP_CREATE, &buf[2], + &buf[2 + 4]); + _convertion_ac_methode(file, HIGH, SC_AC_OP_INVALIDATE, + &buf[3], &buf[3 + 4]); + buflen = 10; + break; + case SC_FILE_TYPE_INTERNAL_EF: + buf[0] |= 0x80; + case SC_FILE_TYPE_WORKING_EF: + switch (file->ef_structure) { + case SC_FILE_EF_TRANSPARENT: + buf[0] |= 0x20; /* pas de support transaction */ + buf[1] |= 0; + _convertion_ac_methode(file, HIGH, SC_AC_OP_READ, + &buf[2], &buf[2 + 4]); + _convertion_ac_methode(file, LOW, SC_AC_OP_UPDATE, + &buf[2], &buf[2 + 4]); + _convertion_ac_methode(file, HIGH, SC_AC_OP_INVALIDATE, + &buf[3], &buf[3 + 4]); + _convertion_ac_methode(file, LOW, SC_AC_OP_ERASE, + &buf[3], &buf[3 + 4]); + buf[10] = (u8) ((file->size) / 256); + buf[11] = (u8) ((file->size) % 256); + break; + case SC_FILE_EF_LINEAR_FIXED: + buf[0] |= 0x40; /* pas de support transaction */ + buf[1] |= 0; + _convertion_ac_methode(file, HIGH, SC_AC_OP_READ, + &buf[2], &buf[2 + 4]); + _convertion_ac_methode(file, LOW, SC_AC_OP_UPDATE, + &buf[2], &buf[2 + 4]); + _convertion_ac_methode(file, HIGH, SC_AC_OP_INVALIDATE, + &buf[3], &buf[3 + 4]); + buf[10] = file->record_count; + buf[11] = file->record_length; + break; + case SC_FILE_EF_CYCLIC: + buf[0] |= 0x60; /* pas de support transaction */ + buf[1] |= 0; + _convertion_ac_methode(file, HIGH, SC_AC_OP_READ, + &buf[2], &buf[2 + 4]); + _convertion_ac_methode(file, LOW, SC_AC_OP_UPDATE, + &buf[2], &buf[2 + 4]); + _convertion_ac_methode(file, HIGH, SC_AC_OP_INVALIDATE, + &buf[3], &buf[3 + 4]); + buf[10] = file->record_count; + buf[11] = file->record_length; + break; + case SC_FILE_EF_LINEAR_VARIABLE: + case SC_FILE_EF_UNKNOWN: + case SC_FILE_EF_LINEAR_FIXED_TLV: + case SC_FILE_EF_LINEAR_VARIABLE_TLV: + case SC_FILE_EF_CYCLIC_TLV: + default: + return SC_ERROR_NOT_SUPPORTED; + } + break; + default: + return SC_ERROR_NOT_SUPPORTED; + } + if (file->shareable) + buf[0] |= 0x08; + if (file->path.len >= 2) { + p1 = file->path.value[file->path.len - 2]; + p2 = file->path.value[file->path.len - 1]; + } + + else if (file->id) { + p1 = (file->id) / 256; + p2 = (file->id) % 256; + } + if (card->ctx->debug >= 3) + sc_debug(card->ctx, "create file %s, id %X size %d\n", + file->path.value, file->id, file->size); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, p1, p2); + apdu.cla = 0x80; + apdu.lc = buflen; + apdu.datalen = buflen; + apdu.data = buf; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + return r; +} + +static int westcos_delete_file(sc_card_t * card, const sc_path_t * path_in) +{ + int r; + sc_apdu_t apdu; + if (card == NULL || path_in == NULL || path_in->len < 2) + return SC_ERROR_INVALID_ARGUMENTS; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_delete_file\n"); + if (path_in->len > 2) { + r = sc_select_file(card, path_in, NULL); + if (r) + return (r); + } + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, + path_in->value[path_in->len - 2], + path_in->value[path_in->len - 1]); + apdu.cla = 0x80; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return (r); + return 0; +} + +static int westcos_list_files(sc_card_t * card, u8 * buf, size_t buflen) +{ + int r; + sc_apdu_t apdu; + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_list_files\n"); + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x34, 0x00, 0x00); + apdu.cla = 0x80; + apdu.le = buflen; + apdu.resplen = buflen; + apdu.resp = buf; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return (r); + return apdu.resplen; +} + +static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, + u8 * result, size_t * len) +{ + int r; + DES_key_schedule ks1, ks2; + u8 buf[8]; + if ((*len) < sizeof(buf)) + return SC_ERROR_INVALID_ARGUMENTS; + *len = 8; + r = sc_get_challenge(card, buf, *len); + if (r) + return r; + DES_set_key((const_DES_cblock *) & key[0], &ks1); + DES_set_key((const_DES_cblock *) & key[8], &ks2); + DES_ecb2_encrypt((const_DES_cblock *)buf, (DES_cblock*)result, &ks1, &ks2, DES_ENCRYPT); + return 0; +} + +static int westcos_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, + int *tries_left) +{ + int r; + u8 buf[20]; //, result[20]; + sc_apdu_t apdu; + size_t len = 0; + int pad = 0, use_pin_pad = 0, ins, p1 = 0; + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, + "westcos_pin_cmd:data->pin_type=%X, data->cmd=%X\n", + data->pin_type, data->cmd); + if (tries_left) + *tries_left = -1; + switch (data->pin_type) { + case SC_AC_AUT: + len = sizeof(buf); + r = westcos_get_crypte_challenge(card, data->pin1.data, buf, + &len); + if (r) + return (r); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x82, 0x00, + data->pin_reference); + apdu.lc = len; + apdu.datalen = len; + apdu.data = buf; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + return sc_check_sw(card, apdu.sw1, apdu.sw2); + break; + case SC_AC_CHV: + if (data->flags & SC_PIN_CMD_NEED_PADDING) + pad = 1; + if (data->flags & SC_PIN_CMD_USE_PINPAD) + use_pin_pad = 1; + data->pin1.offset = 0; + data->pin1.encoding = SC_PIN_ENCODING_GLP; + if (data->pin1.min_length == 0) + data->pin1.min_length = 4; + if (data->pin1.max_length == 0) + data->pin1.max_length = 12; + switch (data->cmd) { + case SC_PIN_CMD_VERIFY: + ins = 0x20; + if ((r = + sc_build_pin(buf, sizeof(buf), &data->pin1, + pad)) < 0) + return r; + len = r; + break; + case SC_PIN_CMD_CHANGE: + ins = 0x24; + if (data->pin1.len != 0 || use_pin_pad) { + if ((r = + sc_build_pin(buf, sizeof(buf), + &data->pin1, pad)) < 0) + return r; + len += r; + } else { + + /* implicit test */ + p1 = 1; + } + data->pin2.offset = data->pin1.offset + len; + data->pin2.encoding = SC_PIN_ENCODING_GLP; + if ((r = + sc_build_pin(buf + len, sizeof(buf) - len, + &data->pin2, pad)) < 0) + return r; + len += r; + break; + case SC_PIN_CMD_UNBLOCK: + ins = 0x2C; + if (data->pin1.len != 0 || use_pin_pad) { + if ((r = + sc_build_pin(buf, sizeof(buf), + &data->pin1, pad)) < 0) + return r; + len += r; + } else { + p1 |= 0x02; + } + if (data->pin2.len != 0 || use_pin_pad) { + data->pin2.offset = data->pin1.offset + len; + data->pin2.encoding = SC_PIN_ENCODING_GLP; + if ((r = + sc_build_pin(buf + len, sizeof(buf) - len, + &data->pin2, pad)) < 0) + return r; + len += r; + } else { + p1 |= 0x01; + } + break; + default: + return SC_ERROR_NOT_SUPPORTED; + } + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, ins, p1, + data->pin_reference); + apdu.lc = len; + apdu.datalen = len; + apdu.data = buf; + apdu.resplen = 0; + apdu.sensitive = 1; + if (!use_pin_pad) { + + /* Transmit the APDU to the card */ + r = sc_transmit_apdu(card, &apdu); + + /* Clear the buffer - it may contain pins */ + sc_mem_clear(buf, sizeof(buf)); + } else { + data->apdu = &apdu; + if (card->reader + && card->reader->ops + && card->reader->ops->perform_verify) { + r = card->reader->ops->perform_verify(card-> + reader, + card-> + slot, + data); + } else { + r = SC_ERROR_NOT_SUPPORTED; + } + } + if (r) + return (r); + return sc_check_sw(card, apdu.sw1, apdu.sw2); + default: + return SC_ERROR_NOT_SUPPORTED; + } +} + +static int sc_get_atr(sc_card_t * card) +{ + int r; + sc_apdu_t apdu; + u8 buf[sizeof(card->atr)]; + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xEC, 0x00, 0x00); + apdu.cla = 0x80; + apdu.le = 0x0d; + apdu.resplen = 0x0d; + apdu.resp = buf; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return (r); + memcpy(card->atr, buf, sizeof(card->atr)); + card->atr_len = apdu.resplen; + return r; +} + +static int sc_lock_phase(sc_card_t * card, u8 phase) +{ + int r; + sc_apdu_t apdu; + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x16, phase, 0x00); + apdu.cla = 0x80; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + return sc_check_sw(card, apdu.sw1, apdu.sw2); +} + +static int westcos_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) +{ + int r; + size_t buflen; + u8 buf[256]; + sc_apdu_t apdu; + struct sc_pin_cmd_data data; + sc_serial_number_t *serialnr; + priv_data_t *priv_data = NULL; + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_card_ctl cmd = %X\n", cmd); + priv_data = (priv_data_t *) card->drv_data; + switch (cmd) { + case SC_CARDCTL_GET_DEFAULT_KEY: + return westcos_get_default_key(card, + (struct sc_cardctl_default_key + *)ptr); + break; + case SC_CARDCTL_LIFECYCLE_SET: + if (1) { + int mode = *((int *)ptr); + switch (mode) { + case SC_CARDCTRL_LIFECYCLE_ADMIN: + if (priv_data->flags & JAVACARD) { + return 0; + } + if (card->atr[10] == 0x80 + || card->atr[10] == 0x81) + return 0; + return SC_ERROR_CARD_CMD_FAILED; + case SC_CARDCTRL_LIFECYCLE_USER: + if (card->atr[10] == 0x80) { + r = sc_lock_phase(card, 0x02); + if (r) + return (r); + r = sc_get_atr(card); + if (r) + return (r); + r = sc_card_ctl(card, + SC_CARDCTL_WESTCOS_AUT_KEY, + NULL); + if (r) + return (r); + } + if (card->atr[10] == 0x81) { + r = sc_lock_phase(card, 0x01); + if (r) + return (r); + r = sc_get_atr(card); + if (r) + return (r); + return 0; + } + return SC_ERROR_CARD_CMD_FAILED; + case SC_CARDCTRL_LIFECYCLE_OTHER: + default: + break; + } + } + break; + case SC_CARDCTL_GET_SERIALNR: + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xEE, 0x00, + 0x00); + apdu.cla = 0xb0; + apdu.le = 8; + apdu.resp = buf; + apdu.resplen = 10; /* include SW's */ + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return (r); + if (SC_MAX_SERIALNR < 8) + return SC_ERROR_NOT_SUPPORTED; + serialnr = (sc_serial_number_t *) ptr; + serialnr->len = 8; + memcpy(serialnr->value, buf, serialnr->len); + return 0; + case SC_CARDCTL_WESTCOS_CREATE_MF: + buf[0] = *((u8 *) ptr); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x3F, + 0x00); + apdu.cla = 0x80; + apdu.lc = 1; + apdu.datalen = 1; + apdu.data = buf; + apdu.le = 0; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + return sc_check_sw(card, apdu.sw1, apdu.sw2); + case SC_CARDCTL_WESTCOS_COMMIT: + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2C, 0x00, 0x00); + apdu.cla = 0x80; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return (r); + return r; + case SC_CARDCTL_WESTCOS_ROLLBACK: + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x00, 0x00); + apdu.cla = 0x80; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return (r); + return r; + case SC_CARDCTL_WESTCOS_AUT_KEY: + if (ptr != NULL) + priv_data->default_key = *((sc_autkey_t *) ptr); + memset(&data, 0, sizeof(data)); + data.pin_type = SC_AC_AUT; + data.pin_reference = priv_data->default_key.key_reference; + data.pin1.len = priv_data->default_key.key_len; + data.pin1.data = priv_data->default_key.key_value; + return sc_pin_cmd(card, &data, NULL); + case SC_CARDCTL_WESTCOS_CHANGE_KEY: + if (1) { + int lrc; + u8 temp[7]; + sc_changekey_t *ck = (sc_changekey_t *) ptr; + sc_autkey_t master_key; + if (ck->master_key.key_len != 0) + master_key = ck->master_key; + + else + master_key = priv_data->default_key; + memcpy(temp, ck->key_template, sizeof(temp)); + westcos_compute_aetb_crc(CRC_A, ck->new_key.key_value, + ck->new_key.key_len, &temp[5], &temp[6]); + for (r = 0, temp[4] = 0xAA, lrc = 0; r < sizeof(temp); + r++) + lrc += temp[r]; + temp[4] = (lrc % 256); + buflen = sizeof(buf); + r = westcos_get_crypte_challenge(card, + master_key.key_value, + buf, &buflen); + if (r) + return (r); + memcpy(&buf[buflen], temp, sizeof(temp)); + buflen += sizeof(temp); + memcpy(&buf[buflen], ck->new_key.key_value, + ck->new_key.key_len); + buflen += ck->new_key.key_len; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, + 0xD8, ck->new_key.key_reference, + master_key.key_reference); + apdu.cla = 0x80; + apdu.lc = buflen; + apdu.datalen = buflen; + apdu.data = buf; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return (r); + return r; + } + case SC_CARDCTL_WESTCOS_SET_DEFAULT_KEY: + priv_data->default_key = *((sc_autkey_t *) ptr); + return 0; + case SC_CARDCTL_WESTCOS_LOAD_DATA: + + /* ptr[0] = 0x01 pour generique appli, 0x81 pour appli avec pme */ + buf[0] = *((u8 *) ptr); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xB2, 0x80, + 0x14); + apdu.cla = 0xB0; + apdu.lc = 1; + apdu.datalen = 1; + apdu.data = buf; + r = sc_transmit_apdu(card, &apdu); + if (r) + return (r); + return sc_check_sw(card, apdu.sw1, apdu.sw2); + } + return SC_ERROR_NOT_SUPPORTED; +} +static int westcos_set_security_env(sc_card_t *card, + const struct sc_security_env *env, + int se_num) +{ + priv_data_t *priv_data = NULL; + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_set_security_env\n"); + priv_data = (priv_data_t *) card->drv_data; + priv_data->env = *env; + return 0; +} + +static int westcos_restore_security_env(sc_card_t *card, int se_num) +{ + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_restore_security_env\n"); + return 0; +} + +static int westcos_sign_decipher(int mode, sc_card_t *card, + const u8 * data, size_t data_len, u8 * out, + size_t outlen) +{ + int r; + int idx = 0; + u8 buf[180]; + sc_file_t *keyfile = sc_file_new(); + priv_data_t *priv_data = NULL; + int pad; + +#ifdef ENABLE_OPENSSL + RSA *rsa = NULL; + BIO *mem = BIO_new(BIO_s_mem()); + +#endif + if (card == NULL) + return SC_ERROR_INVALID_ARGUMENTS; + if (card->ctx->debug >= 1) + sc_debug(card->ctx, "westcos_sign_decipher\n"); + priv_data = (priv_data_t *) card->drv_data; + if (keyfile == NULL || mem == NULL || priv_data == NULL) { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } +#ifndef ENABLE_OPENSSL + r = SC_ERROR_NOT_SUPPORTED; + +#else + if ((priv_data->env.flags) & SC_ALGORITHM_RSA_PAD_PKCS1) + pad = RSA_PKCS1_PADDING; + + else if ((priv_data->env.flags) & SC_ALGORITHM_RSA_RAW) + pad = RSA_NO_PADDING; + + else { + r = SC_ERROR_INVALID_ARGUMENTS; + goto out; + } + r = sc_select_file(card, &(priv_data->env.file_ref), &keyfile); + if (r) + goto out; + + do { + int alire; + alire = min(((keyfile->size) - idx), sizeof(buf)); + if (alire <= 0) + break; + if (card->ctx->debug >= 5) + sc_debug(card->ctx, "idx = %d, alire=%d\n", idx, alire); + r = sc_read_binary(card, idx, buf, alire, 0); + if (r < 0) + goto out; + BIO_write(mem, buf, r); + idx += r; + } while (1); + BIO_set_mem_eof_return(mem, -1); + if (!d2i_RSAPrivateKey_bio(mem, &rsa)) { + if (card->ctx->debug >= 5) + sc_debug(card->ctx, "RSA clef invalide, %d\n", + ERR_get_error()); + r = SC_ERROR_UNKNOWN; + goto out; + } + + /* pkcs11 reroute routine cryptage vers la carte */ + rsa->meth = RSA_PKCS1_SSLeay(); + if (RSA_size(rsa) > outlen) { + if (card->ctx->debug >= 5) + sc_debug(card->ctx, "Buffer too small\n"); + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } +#if 1 + if (mode) { /* decipher */ + r = RSA_private_decrypt(data_len, data, out, rsa, pad); + if (r == -1) { + +#ifdef DEBUG_SSL + print_openssl_erreur(); + +#endif + if (card->ctx->debug >= 5) + sc_debug(card->ctx, "Decipher error %d\n", + ERR_get_error()); + r = SC_ERROR_UNKNOWN; + goto out; + } + } + + else { /* signature */ + + r = RSA_private_encrypt(data_len, data, out, rsa, pad); + if (r == -1) { + +#ifdef DEBUG_SSL + print_openssl_erreur(); + +#endif + if (card->ctx->debug >= 5) + sc_debug(card->ctx, "Signature error %d\n", + ERR_get_error()); + r = SC_ERROR_UNKNOWN; + goto out; + } + } + +#else + if (RSA_sign(nid, data, data_len, out, &outlen, rsa) != 1) { + if (card->ctx->debug >= 5) + sc_debug(card->ctx, "RSA_sign error %d \n", + ERR_get_error()); + r = SC_ERROR_UNKNOWN; + goto out; + } + r = outlen; + +#endif +#endif /* ENABLE_OPENSSL */ + out: +#ifdef ENABLE_OPENSSL + if (mem) + BIO_free(mem); + if (rsa) + RSA_free(rsa); + +#endif + if (keyfile) + sc_file_free(keyfile); + return r; +} + +static int westcos_compute_signature(sc_card_t *card, const u8 * data, + size_t data_len, u8 * out, size_t outlen) +{ + return westcos_sign_decipher(0, card, data, data_len, out, outlen); +} + +static int westcos_decipher(sc_card_t *card, const u8 * crgram, + size_t crgram_len, u8 * out, size_t outlen) +{ + return westcos_sign_decipher(1, card, crgram, crgram_len, out, outlen); +} + +struct sc_card_driver *sc_get_westcos_driver(void) +{ + if (iso_ops == NULL) + iso_ops = sc_get_iso7816_driver()->ops; + westcos_ops = *iso_ops; + + westcos_ops.match_card = westcos_match_card; + westcos_ops.init = westcos_init; + westcos_ops.finish = westcos_finish; + /* read_binary */ + /* write_binary */ + /* update_binary */ + westcos_ops.erase_binary = NULL; + /* read_record */ + /* write_record */ + /* append_record */ + /* update_record */ + westcos_ops.select_file = westcos_select_file; + /* get_response */ + /* get_challenge */ + westcos_ops.verify = NULL; + westcos_ops.logout = NULL; + westcos_ops.restore_security_env = westcos_restore_security_env; + westcos_ops.set_security_env = westcos_set_security_env; + westcos_ops.decipher = westcos_decipher; + westcos_ops.compute_signature = westcos_compute_signature; + westcos_ops.change_reference_data = NULL; + westcos_ops.reset_retry_counter = NULL; + westcos_ops.create_file = westcos_create_file; + westcos_ops.delete_file = westcos_delete_file; + westcos_ops.list_files = westcos_list_files; + westcos_ops.check_sw = westcos_check_sw; + westcos_ops.card_ctl = westcos_card_ctl; + westcos_ops.process_fci = westcos_process_fci; + westcos_ops.construct_fci = NULL; + westcos_ops.pin_cmd = westcos_pin_cmd; + westcos_ops.get_data = NULL; + westcos_ops.put_data = NULL; + westcos_ops.delete_record = NULL; + + return &westcos_drv; +} + diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 9483f773..657fa185 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -175,6 +175,19 @@ enum { SC_CARDCTL_RTECP_INIT, SC_CARDCTL_RTECP_INIT_END, SC_CARDCTL_RTECP_GENERATE_KEY, + + /* + * Westcos specific + */ + SC_CARDCTL_WESTCOS_FREEZE = _CTL_PREFIX('W', 'T', 'C'), + SC_CARDCTL_WESTCOS_CREATE_MF, + SC_CARDCTL_WESTCOS_COMMIT, + SC_CARDCTL_WESTCOS_ROLLBACK, + SC_CARDCTL_WESTCOS_AUT_KEY, + SC_CARDCTL_WESTCOS_CHANGE_KEY, + SC_CARDCTL_WESTCOS_SET_DEFAULT_KEY, + SC_CARDCTL_WESTCOS_LOAD_DATA, + }; enum { @@ -461,6 +474,22 @@ typedef struct sc_cardctl_asepcos_activate_file { #define OP_TYPE_GENERATE 0 #define OP_TYPE_STORE 1 +/* + * Westcos + */ + +typedef struct { + int key_reference; + int key_len; //8, 16 or 24 + u8 key_value[24]; +}sc_autkey_t; + +typedef struct { + sc_autkey_t master_key; + sc_autkey_t new_key; + u8 key_template[7]; +}sc_changekey_t; + /* * RuToken types and constants */ diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 044a19fb..465059ba 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -174,6 +174,7 @@ extern sc_card_driver_t *sc_get_akis_driver(void); extern sc_card_driver_t *sc_get_entersafe_driver(void); extern sc_card_driver_t *sc_get_rutoken_driver(void); extern sc_card_driver_t *sc_get_rtecp_driver(void); +extern sc_card_driver_t *sc_get_westcos_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index db9953b5..9b2fb872 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -84,6 +84,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { #endif { "rutoken", (void *(*)(void)) sc_get_rutoken_driver }, { "rutoken_ecp",(void *(*)(void)) sc_get_rtecp_driver }, + { "westcos", (void *(*)(void)) sc_get_westcos_driver }, /* emv is not really used, not sure if it works, but it conflicts with muscle and rutoken driver, thus has to be after them */ { "emv", (void *(*)(void)) sc_get_emv_driver }, diff --git a/src/libopensc/p15emu-westcos.c b/src/libopensc/p15emu-westcos.c new file mode 100644 index 00000000..69e58908 --- /dev/null +++ b/src/libopensc/p15emu-westcos.c @@ -0,0 +1,251 @@ +/* + * p15emu-westcos.c: pkcs15 emulation for westcos card + * + * Copyright (C) 2009 francois.leblanc@cev-sa.com +* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "internal.h" + +#include +#include +#include + +#include "pkcs15.h" +#include "cardctl.h" +#include "compat_strlcpy.h" + +static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) +{ + int i, r; + int modulus_length = 0, usage = 0; + u8 buf[256]; + sc_card_t *card = p15card->card; + sc_context_t *ctx = card->ctx; + sc_serial_number_t serial; + sc_path_t path; + sc_file_t *file = NULL; + sc_format_path("3F00", &path); + r = sc_select_file(card, &path, &file); + if (r) + goto out; + if (file) + sc_file_free(file); + file = NULL; + if (p15card->label != NULL) + free(p15card->label); + p15card->label = strdup("westcos"); + if (p15card->manufacturer_id != NULL) + free(p15card->manufacturer_id); + p15card->manufacturer_id = strdup("CEV"); + + /* get serial number */ + r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); + r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0); + if (r) + goto out; + if (p15card->serial_number != NULL) + free(p15card->serial_number); + p15card->serial_number = strdup(buf); + p15card->version = buf[6]; + p15card->flags = SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED; + sc_format_path("AAAA", &path); + sc_ctx_suppress_errors_on(ctx); + r = sc_select_file(card, &path, &file); + sc_ctx_suppress_errors_off(ctx); + if (!r) { + for (i = 0; i < 1; i++) { + unsigned int flags; + struct sc_pkcs15_pin_info pin_info; + struct sc_pkcs15_object pin_obj; + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + flags = SC_PKCS15_PIN_FLAG_INITIALIZED; + if (i == 1) { + flags |= + SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED | + SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN; + } + pin_info.auth_id.len = 1; + pin_info.auth_id.value[0] = i + 1; + pin_info.reference = i; + pin_info.flags = flags; + pin_info.type = SC_PKCS15_PIN_TYPE_BCD; + pin_info.min_length = 4; + pin_info.stored_length = 8; + pin_info.max_length = 8; + pin_info.pad_char = 0xff; + pin_info.path = path; + pin_info.tries_left = -1; + if (i == 1) + strlcpy(pin_obj.label, "Unblock", + sizeof(pin_obj.label)); + + else + strlcpy(pin_obj.label, "User", + sizeof(pin_obj.label)); + pin_obj.flags = + SC_PKCS15_CO_FLAG_MODIFIABLE | + SC_PKCS15_CO_FLAG_PRIVATE; + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, + &pin_info); + if (r) + goto out; + } + } + if (file) + sc_file_free(file); + file = NULL; + sc_format_path("0002", &path); + sc_ctx_suppress_errors_on(ctx); + r = sc_select_file(card, &path, &file); + sc_ctx_suppress_errors_off(ctx); + if (!r) { + struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_object cert_obj; + struct sc_pkcs15_pubkey_info pubkey_info; + struct sc_pkcs15_object pubkey_obj; + struct sc_pkcs15_pubkey *pkey = NULL; + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); + cert_info.id.len = 1; + cert_info.id.value[0] = 0x45; + cert_info.authority = 0; + cert_info.path = path; + sc_ctx_suppress_errors_on(ctx); + r = sc_pkcs15_read_certificate(p15card, &cert_info, + (sc_pkcs15_cert_t + **) (&cert_obj.data)); + sc_ctx_suppress_errors_off(ctx); + if (!r) { + sc_pkcs15_cert_t *cert = + (sc_pkcs15_cert_t *) (cert_obj.data); + strlcpy(cert_obj.label, "User certificat", + sizeof(cert_obj.label)); + cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE; + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, + &cert_info); + if (r) + goto out; + pkey = &cert->key; + } + memset(&pubkey_info, 0, sizeof(pubkey_info)); + memset(&pubkey_obj, 0, sizeof(pubkey_obj)); + pubkey_info.id.len = 1; + pubkey_info.id.value[0] = 0x45; + pubkey_info.modulus_length = modulus_length; + pubkey_info.key_reference = 1; + pubkey_info.native = 1; + pubkey_info.usage = + SC_PKCS15_PRKEY_USAGE_VERIFY | + SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER | + SC_PKCS15_PRKEY_USAGE_ENCRYPT | + SC_PKCS15_PRKEY_USAGE_WRAP; + pubkey_info.path = path; + strlcpy(pubkey_obj.label, "Public Key", + sizeof(pubkey_obj.label)); + pubkey_obj.auth_id.len = 1; + pubkey_obj.auth_id.value[0] = 1; + pubkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + pubkey_obj.type = SC_PKCS15_TYPE_PUBKEY_RSA; + if (pkey == NULL) { + pubkey_obj.data = &pubkey_info; + r = sc_pkcs15_read_pubkey(p15card, &pubkey_obj, &pkey); + if (r) + goto out; + + //force rechargement clef et maj infos lors de sc_pkcs15emu_add_rsa_pubkey (sinon modulus = 0) + pubkey_obj.flags = 0; + } + if (pkey->algorithm == SC_ALGORITHM_RSA) { + modulus_length = (int)(pkey->u.rsa.modulus.len * 8); + } + pubkey_info.modulus_length = modulus_length; + pubkey_obj.data = pkey; + r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, + &pubkey_info); + if (r < 0) + goto out; + } + if (!usage) { + usage = + SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DECRYPT | + SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; + } + if (file) + sc_file_free(file); + file = NULL; + sc_format_path("0001", &path); + sc_ctx_suppress_errors_on(ctx); + r = sc_select_file(card, &path, &file); + sc_ctx_suppress_errors_off(ctx); + if (!r) { + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); + prkey_info.id.len = 1; + prkey_info.id.value[0] = 0x45; + prkey_info.usage = + SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DECRYPT + | SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; + prkey_info.native = 1; + prkey_info.key_reference = 1; + prkey_info.modulus_length = modulus_length; + prkey_info.path = path; + strlcpy(prkey_obj.label, "Private Key", + sizeof(prkey_obj.label)); + prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + prkey_obj.auth_id.len = 1; + prkey_obj.auth_id.value[0] = 1; + r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, + &prkey_info); + if (r < 0) + goto out; + } + r = 0; + out:if (file) + sc_file_free(file); + return r; +} + +static int westcos_detect_card(sc_pkcs15_card_t * p15card) +{ + sc_card_t *card = p15card->card; + sc_context_t *ctx = card->ctx; + char *name = "WESTCOS"; + if (ctx->debug >= 1) + sc_debug(ctx, "westcos_detect_card (%s)", card->name); + if (strncmp(card->name, name, strlen(name))) + return SC_ERROR_WRONG_CARD; + return SC_SUCCESS; +} + +int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t * p15card, + sc_pkcs15emu_opt_t * opts) +{ + int r; + sc_card_t *card = p15card->card; + sc_context_t *ctx = card->ctx; + if (ctx->debug >= 1) + sc_debug(ctx, "sc_pkcs15_init_func_ex westcos\n"); + if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) + return sc_pkcs15emu_westcos_init(p15card); + r = westcos_detect_card(p15card); + if (r) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_westcos_init(p15card); +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index b0546f56..801f747c 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -28,6 +28,8 @@ #include #include +extern int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *p15card, + sc_pkcs15emu_opt_t *opts); extern int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); extern int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *, @@ -58,6 +60,7 @@ static struct { const char * name; int (*handler)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); } builtin_emulators[] = { + { "westcos", sc_pkcs15emu_westcos_init_ex }, { "openpgp", sc_pkcs15emu_openpgp_init_ex }, { "infocamere", sc_pkcs15emu_infocamere_init_ex }, { "starcert", sc_pkcs15emu_starcert_init_ex }, diff --git a/src/pkcs15init/Makefile.am b/src/pkcs15init/Makefile.am index 5ffdbba6..7f41e86f 100644 --- a/src/pkcs15init/Makefile.am +++ b/src/pkcs15init/Makefile.am @@ -24,7 +24,8 @@ dist_pkgdata_DATA = \ rutoken.profile \ asepcos.profile \ entersafe.profile \ - rutoken_ecp.profile + rutoken_ecp.profile \ + westcos.profile AM_CPPFLAGS = -DSC_PKCS15_PROFILE_DIRECTORY=\"$(pkgdatadir)\" AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(LTLIB_CFLAGS) @@ -32,6 +33,7 @@ INCLUDES = -I$(top_srcdir)/src/common -I$(top_builddir)/src/include libpkcs15init_la_SOURCES = \ pkcs15-lib.c profile.c keycache.c \ + pkcs15-westcos.c \ pkcs15-gpk.c pkcs15-miocos.c pkcs15-cflex.c \ pkcs15-cardos.c pkcs15-jcop.c pkcs15-starcos.c \ pkcs15-oberthur.c pkcs15-setcos.c pkcs15-incrypto34.c \ diff --git a/src/pkcs15init/Makefile.mak b/src/pkcs15init/Makefile.mak index 1626668e..ca23a37f 100644 --- a/src/pkcs15init/Makefile.mak +++ b/src/pkcs15init/Makefile.mak @@ -10,7 +10,7 @@ OBJECTS = pkcs15-lib.obj profile.obj keycache.obj \ pkcs15-cardos.obj pkcs15-jcop.obj pkcs15-starcos.obj \ pkcs15-oberthur.obj pkcs15-setcos.obj pkcs15-incrypto34.obj \ pkcs15-muscle.obj pkcs15-asepcos.obj pkcs15-rutoken.obj \ - pkcs15-entersafe.obj pkcs15-rtecp.obj \ + pkcs15-entersafe.obj pkcs15-rtecp.obj pkcs15-westcos.obj \ versioninfo.res all: install-headers $(TARGET) diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 80dd83b6..8c37a186 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -404,6 +404,7 @@ extern struct sc_pkcs15init_operations *sc_pkcs15init_get_asepcos_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_rutoken_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_entersafe_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_rtecp_ops(void); +extern struct sc_pkcs15init_operations *sc_pkcs15init_get_westcos_ops(void); #ifdef __cplusplus } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 03dbeaa9..6bc05473 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -165,6 +165,7 @@ static struct profile_operations { { "asepcos", (void*) sc_pkcs15init_get_asepcos_ops }, { "entersafe",(void*) sc_pkcs15init_get_entersafe_ops }, { "rutoken_ecp", (void *) sc_pkcs15init_get_rtecp_ops }, + { "westcos", (void *) sc_pkcs15init_get_westcos_ops }, { NULL, NULL }, }; diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c new file mode 100644 index 00000000..321647d7 --- /dev/null +++ b/src/pkcs15init/pkcs15-westcos.c @@ -0,0 +1,464 @@ +/* + * pkcs15-westcos.c: pkcs15 support for westcos card + * + * Copyright (C) 2009 francois.leblanc@cev-sa.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include "pkcs15-init.h" +#include "profile.h" + +#ifdef ENABLE_OPENSSL +#include +#include +#include + + +#include +#include +#endif + +extern int sc_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2); + +#if 0 +/* + * Get private and public key file + */ +static int _westcos_get_keyfiles(sc_profile_t *profile, sc_card_t *card, + const sc_path_t *df_path, + sc_file_t **prkf, sc_file_t **pukf) +{ + sc_path_t path = *df_path; + int r; + + /* Get the private key file */ + r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &path, prkf); + if (r < 0) { + char pbuf[SC_MAX_PATH_STRING_SIZE]; + + r = sc_path_print(pbuf, sizeof(pbuf), &path); + if (r != SC_SUCCESS) + pbuf[0] = '\0'; + + return r; + } + + /* Get the public key file */ + path.len -= 2; + sc_append_file_id(&path, 0x1012); + r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &path, pukf); + if (r < 0) { + sc_file_free(*prkf); + return r; + } + + return 0; +} +#endif /* currently unused */ + +static int westcos_pkcs15init_init_card(sc_profile_t *profile, + sc_card_t *card) +{ + int r; + struct sc_path path; + + sc_format_path("3F00", &path); + r = sc_select_file(card, &path, NULL); + if(r) return (r); + + return r; +} + +static int westcos_pkcs15init_create_dir(sc_profile_t *profile, + sc_card_t *card, + sc_file_t *df) +{ + int r; + + /* Create the application DF */ + r = sc_pkcs15init_create_file(profile, card, df); + //if(r) return r; + + r = sc_select_file(card, &df->path, NULL); + if(r) return r; + + return 0; +} + +#if 0 +/* +* Create a PIN domain (i.e. a sub-directory holding a user PIN) +*/ +static int westcos_pkcs15init_create_domain(sc_profile_t *profile, + sc_card_t *card, + const sc_pkcs15_id_t *id, + sc_file_t **ret) +{ + return SC_ERROR_NOT_SUPPORTED; //sc_pkcs15_create_pin_domain(profile, card, id, ret); +} +#endif /* currently unused */ + +/* + * Select the PIN reference + */ +static int westcos_pkcs15_select_pin_reference(sc_profile_t *profile, + sc_card_t *card, + sc_pkcs15_pin_info_t *pin_info) +{ + + if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { + pin_info->reference = 1; + } else { + pin_info->reference = 0; + } + + return 0; +} + +/* + * Create a new PIN inside a DF + */ +static int westcos_pkcs15_create_pin(sc_profile_t *profile, + sc_card_t *card, sc_file_t *df, + sc_pkcs15_object_t *pin_obj, + const u8 *pin, size_t pin_len, + const u8 *puk, size_t puk_len) +{ + int r; + sc_file_t *file = sc_file_new(); + sc_path_t path; + + if(pin_len>9 || puk_len>9 || pin_len<0 || puk_len<0) + return SC_ERROR_INVALID_ARGUMENTS; + + file->type = SC_FILE_TYPE_INTERNAL_EF; + file->ef_structure = SC_FILE_EF_TRANSPARENT; + file->shareable = 0; + + file->id = 0xAAAA; + file->size = 37; + + r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_NONE, 0); + if(r) return r; + r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_NONE, 0); + if(r) return r; + r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_NONE, 0); + if(r) return r; + + r = sc_create_file(card, file); + if(r) + { + if(r != SC_ERROR_FILE_ALREADY_EXISTS) + return (r); + + sc_format_path("3F005015AAAA", &path); + r = sc_select_file(card, &path, NULL); + if(r) return (r); + } + + //r = sc_pkcs15init_create_file(profile, card, file); + + if(file) + sc_file_free(file); + + if(pin != NULL) + { + sc_changekey_t ck; + struct sc_pin_cmd_pin pin_cmd; + + memset(&pin_cmd, 0, sizeof(pin_cmd)); + memset(&ck, 0, sizeof(ck)); + + memcpy(ck.key_template, "\x1e\x00\x00\x10", 4); + + pin_cmd.encoding = SC_PIN_ENCODING_GLP; + pin_cmd.len = pin_len; + pin_cmd.data = pin; + pin_cmd.max_length = 8; + + ck.new_key.key_len = sc_build_pin(ck.new_key.key_value, + sizeof(ck.new_key.key_value), &pin_cmd, 1); + if(ck.new_key.key_len<0) + return SC_ERROR_CARD_CMD_FAILED; + + r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck); + if(r) return r; + } + + if(puk != NULL) + { + sc_changekey_t ck; + struct sc_pin_cmd_pin puk_cmd; + + memset(&puk_cmd, 0, sizeof(puk_cmd)); + memset(&ck, 0, sizeof(ck)); + + memcpy(ck.key_template, "\x1e\x00\x00\x20", 4); + + puk_cmd.encoding = SC_PIN_ENCODING_GLP; + puk_cmd.len = puk_len; + puk_cmd.data = puk; + puk_cmd.max_length = 8; + + ck.new_key.key_len = sc_build_pin(ck.new_key.key_value, + sizeof(ck.new_key.key_value), &puk_cmd, 1); + if(ck.new_key.key_len<0) + return SC_ERROR_CARD_CMD_FAILED; + + r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck); + if(r) return r; + } + + return 0; +} + +/* + * Create a new key file + */ +static int westcos_pkcs15init_create_key(sc_profile_t *profile, + sc_card_t *card, + sc_pkcs15_object_t *obj) +{ + int r; + size_t size; + sc_file_t *keyfile = NULL; + sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; + + if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { + return SC_ERROR_NOT_SUPPORTED; + } + + switch (key_info->modulus_length) { + case 128: size = 112; break; + case 256: size = 184; break; + case 512: size = 336; break; + case 768: size = 480; break; + case 1024: size = 616; break; + case 1536: size = 912; break; + case 2048: size = 1200; break; + default: + r = SC_ERROR_INVALID_ARGUMENTS; + goto out; + } + + keyfile = sc_file_new(); + if(keyfile == NULL) + return SC_ERROR_OUT_OF_MEMORY; + + keyfile->path = key_info->path; + + keyfile->type = SC_FILE_TYPE_WORKING_EF; + keyfile->ef_structure = SC_FILE_EF_TRANSPARENT; + keyfile->shareable = 0; + keyfile->size = size; + + r = sc_file_add_acl_entry(keyfile, SC_AC_OP_READ, SC_AC_CHV, 0); + if(r) goto out; + r = sc_file_add_acl_entry(keyfile, SC_AC_OP_UPDATE, SC_AC_CHV, 0); + if(r) goto out; + r = sc_file_add_acl_entry(keyfile, SC_AC_OP_ERASE, SC_AC_CHV, 0); + if(r) goto out; + + r = sc_pkcs15init_create_file(profile, card, keyfile); + if(r) + { + if(r != SC_ERROR_FILE_ALREADY_EXISTS) + goto out; + r = 0; + } + +out: + if(keyfile) + sc_file_free(keyfile); + + return r; +} + + + +/* + * Store a private key + */ +static int westcos_pkcs15init_store_key(sc_profile_t *profile, + sc_card_t *card, + sc_pkcs15_object_t *obj, + sc_pkcs15_prkey_t *key) +{ + return SC_ERROR_NOT_SUPPORTED; + +#if 0 + int r; + sc_file_t *keyfile; + sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; + + if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { + return SC_ERROR_NOT_SUPPORTED; + } + + r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &key_info->path, &keyfile); + if (r < 0) return r; + + //r = sc_pkcs15init_update_file(profile, card, keyfile, &key->der.data, &key->der.len); + + //sc_file_free(keyfile); + return r; +#endif +} + +/* + * Generate key + */ +static int westcos_pkcs15init_generate_key(sc_profile_t *profile, + sc_card_t *card, + sc_pkcs15_object_t *obj, + sc_pkcs15_pubkey_t *pubkey) +{ + int r = SC_ERROR_UNKNOWN; + long lg; + char *p; + sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; +#ifdef ENABLE_OPENSSL + RSA *rsa = RSA_new(); + BIGNUM *bn = BN_new(); + BIO *mem = BIO_new(BIO_s_mem()); +#endif + +#ifndef ENABLE_OPENSSL + r = SC_ERROR_NOT_SUPPORTED; +#else + sc_file_t *prkf = NULL; + + if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { + return SC_ERROR_NOT_SUPPORTED; + } + + if(/*keyfile == NULL ||*/ rsa == NULL || bn == NULL || mem == NULL) + { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } + + /* pkcs11 re-route routine cryptage vers la carte fixe default to use openssl */ + rsa->meth = RSA_PKCS1_SSLeay(); + + if(!BN_set_word(bn, RSA_F4) || + !RSA_generate_key_ex(rsa, key_info->modulus_length, bn, NULL)) + { + r = SC_ERROR_UNKNOWN; + goto out; + } + + if(pubkey != NULL) + { + if(!i2d_RSAPublicKey_bio(mem, rsa)) + { + r = SC_ERROR_UNKNOWN; + goto out; + } + + lg = BIO_get_mem_data(mem, &p); + + pubkey->algorithm = SC_ALGORITHM_RSA; + + r = sc_pkcs15_decode_pubkey(card->ctx, pubkey, p, lg); + } + + BIO_reset(mem); + + if(!i2d_RSAPrivateKey_bio(mem, rsa)) + { + r = SC_ERROR_UNKNOWN; + goto out; + } + + lg = BIO_get_mem_data(mem, &p); + + /* Get the private key file */ + r = sc_profile_get_file_by_path(profile, &key_info->path, &prkf); + if (r < 0) + { + char pbuf[SC_MAX_PATH_STRING_SIZE]; + + r = sc_path_print(pbuf, sizeof(pbuf), &key_info->path); + if (r != SC_SUCCESS) + pbuf[0] = '\0'; + + return r; + } + + r = sc_pkcs15init_update_file(profile, card, prkf, p, lg); + if(r) goto out; + +out: + if(mem) + BIO_free(mem); + if(bn) + BN_free(bn); + if(rsa) + RSA_free(rsa); + if(prkf) + sc_file_free(prkf); +#endif + + return r; +} + +static int westcos_pkcs15init_finalize_card(sc_card_t *card) +{ + int r; + + /* be sure authentificate card */ + r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL); + if(r) return (r); + + return sc_pkcs15init_set_lifecycle(card, SC_CARDCTRL_LIFECYCLE_USER); +} + +static struct sc_pkcs15init_operations sc_pkcs15init_westcos_operations = { + NULL, /* erase_card */ + westcos_pkcs15init_init_card, /* init_card */ + westcos_pkcs15init_create_dir, /* create_dir */ + NULL, /* create_domain */ + westcos_pkcs15_select_pin_reference,/* select_pin_reference */ + westcos_pkcs15_create_pin, /* create_pin */ + NULL, /* select_key_reference */ + westcos_pkcs15init_create_key, /* create_key */ + westcos_pkcs15init_store_key, /* store_key */ + westcos_pkcs15init_generate_key, /* generate_key */ + NULL, NULL, /* encode private/public key */ + westcos_pkcs15init_finalize_card, /* finalize_card */ + NULL,NULL,NULL,NULL, /* old style app */ + NULL, /* old_generate_key */ + NULL /* delete_object */ +}; + +struct sc_pkcs15init_operations* sc_pkcs15init_get_westcos_ops(void) +{ + return &sc_pkcs15init_westcos_operations; +} + + + diff --git a/src/pkcs15init/westcos.profile b/src/pkcs15init/westcos.profile new file mode 100644 index 00000000..957912fd --- /dev/null +++ b/src/pkcs15init/westcos.profile @@ -0,0 +1,183 @@ + +cardinfo { + label = "westcos"; + manufacturer = "CEV"; + + max-pin-length = 8; + min-pin-length = 4; + pin-encoding = BCD; + pin-pad-char = 0xff; + +} + +# Default settings. +# This option block will always be processed. +option default { + macros { + protected = *=$PIN, READ=NONE; + unprotected = *=NONE; + private = *=$PIN; + so-pin-flags = local, initialized, needs-padding; #, soPin; + so-min-pin-length = 6; + so-pin-attempts = 2; + so-auth-id = 1; #FF; + so-puk-attempts = 4; + so-min-puk-length = 6; + unusedspace-size = 128; + odf-size = 256; + aodf-size = 256; + cdf-size = 512; + prkdf-size = 256; + pukdf-size = 256; + dodf-size = 256; + } +} + +PIN so-pin { + auth-id = 1; + reference = 1; + attempts = 3; + min-length = 4; + max-length = 8; + flags = local, initialized, needs-padding; +} +PIN so-puk { + auth-id = 2; + reference = 2; + attempts = 10; + min-length = 4; + max-length = 8; + flags = local, initialized, needs-padding; +} +PIN user-pin { + auth-id = 1; + reference = 1; + attempts = 3; + min-length = 4; + max-length = 8; + flags = local, initialized, needs-padding; +} +PIN user-puk { + auth-id = 2; + reference = 2; + attempts = 10; + min-length = 4; + max-length = 8; + flags = local, initialized, needs-padding; +} + +filesystem { + DF MF { + path = 3F00; + type = DF; + + # This is the DIR file + EF DIR { + type = EF; + file-id = 2F00; + size = 128; + acl = $unprotected; + } + + # Here comes the application DF + DF PKCS15-AppDF { + type = DF; + file-id = 5015; + aid = A0:00:00:00:63:50:4B:43:53:2D:31:35; + acl = $unprotected; + size = 5000; + + EF PKCS15-ODF { + file-id = 5031; + size = $odf-size; + acl = $unprotected; + } + + EF PKCS15-TokenInfo { + file-id = 5032; + acl = $unprotected; + } + + EF PKCS15-UnusedSpace { + file-id = 5033; + size = $unusedspace-size; + acl = $unprotected; + } + + EF PKCS15-AODF { + file-id = 4401; + size = $aodf-size; + acl = $protected; + } + + EF PKCS15-PrKDF { + file-id = 4402; + size = $prkdf-size; + acl = $protected; + } + + EF PKCS15-PuKDF { + file-id = 4403; + size = $pukdf-size; + acl = $protected; + } + + EF PKCS15-CDF { + file-id = 4404; + size = $cdf-size; + acl = $protected; + } + + EF PKCS15-DODF { + file-id = 4405; + size = $dodf-size; + ACL = $protected; + } + + + # This template defines files for keys, certificates etc. + # + # When instantiating the template, each file id will be + # combined with the last octet of the object's pkcs15 id + # to form a unique file ID. + template key-domain { + EF private-key { + file-id = 0100; + structure = transparent; + acl = *=NEVER, READ=$PIN, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + EF public-key { + file-id = 0200; + structure = transparent; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + # Certificate template + EF certificate { + file-id = 0300; + structure = transparent; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + # data objects are stored in transparent EFs. + EF data { + file-id = 0400; + structure = transparent; + acl = *=NEVER, READ=NONE, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + + # private data objects are stored in transparent EFs. + EF privdata { + file-id = 0500; + structure = transparent; + acl = *=NEVER, READ=$PIN, UPDATE=$PIN, WRITE=$PIN, DELETE=$PIN; + } + } + + } + } +} + + + diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am index cac0e06c..20af2088 100644 --- a/src/tools/Makefile.am +++ b/src/tools/Makefile.am @@ -9,7 +9,7 @@ noinst_HEADERS = util.h bin_PROGRAMS = opensc-tool opensc-explorer pkcs15-tool pkcs15-crypt \ pkcs11-tool cardos-tool eidenv rutoken-tool if ENABLE_OPENSSL -bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool +bin_PROGRAMS += cryptoflex-tool pkcs15-init netkey-tool piv-tool westcos-tool endif dist_bin_SCRIPTS = cardos-info if WIN32 @@ -44,6 +44,8 @@ netkey_tool_SOURCES = netkey-tool.c netkey_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) rutoken_tool_SOURCES = rutoken-tool.c util.c rutoken_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) +westcos_tool_SOURCES = westcos-tool.c +westcos_tool_LDADD = $(OPTIONAL_OPENSSL_LIBS) if WIN32 opensc_tool_SOURCES += versioninfo.rc @@ -58,6 +60,7 @@ cardos_tool_SOURCES += versioninfo.rc eidenv_SOURCES += versioninfo.rc netkey_tool_SOURCES += versioninfo.rc rutoken_tool_SOURCES += versioninfo.rc +westcos_tool_SOURCES += versioninfo.rc else dist_noinst_DATA = versioninfo.rc endif diff --git a/src/tools/Makefile.mak b/src/tools/Makefile.mak index ef2c8c66..e4325874 100644 --- a/src/tools/Makefile.mak +++ b/src/tools/Makefile.mak @@ -5,7 +5,7 @@ TOPDIR = ..\.. TARGETS = opensc-tool.exe opensc-explorer.exe pkcs15-tool.exe pkcs15-crypt.exe \ pkcs11-tool.exe cardos-info.exe eidenv.exe rutoken-tool.exe \ - netkey-tool.exe \ + netkey-tool.exe westcos-tool.exe \ $(PROGRAMS_OPENSSL) all: $(TARGETS) diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c new file mode 100644 index 00000000..3ddc2471 --- /dev/null +++ b/src/tools/westcos-tool.c @@ -0,0 +1,942 @@ +/* + * westcos-tool.exe: tool for westcos card + * + * Copyright (C) 2009 francois.leblanc@cev-sa.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static char *version ="0.0.6"; + +static char *nom_card = "WESTCOS"; + +static int finalise = 0; +static int verbose = 0; +static int install_pin = 0; +static int remplace = 0; + +static char *pin = NULL; +static char *puk = NULL; +static char *cert = NULL; + +static int keylen = 0; + +static int no_lecteur = -1; + +static int new_pin = 0; +static int debloque = 0; + +static char *get_filename = NULL; +static char *get_path = NULL; +static char *put_filename = NULL; +static char *put_path = NULL; + +static int do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src) +{ + if (src == 0) return 0; + dst->len = BN_num_bytes(src); + dst->data = (u8 *) malloc(dst->len); + BN_bn2bin(src, dst->data); + return 1; +} + +static int charge = 0; +static void print_openssl_erreur(void) +{ + long r; + + if (!charge) + { + ERR_load_crypto_strings(); + charge = 1; + } + + while ((r = ERR_get_error()) != 0) + fprintf(stderr, "%s\n", ERR_error_string(r, NULL)); +} + +static verify_pin(sc_card_t *card, int pin_reference, char *pin_value) +{ + int r, tries_left = -1; + struct sc_pin_cmd_data data; + + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_VERIFY; + + data.pin_type = SC_AC_CHV; + + data.pin_reference = pin_reference; + + data.flags = SC_PIN_CMD_NEED_PADDING; + + if (card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) + { + printf("Please enter PIN on the reader's pin pad.\n"); + data.pin1.prompt = "Please enter PIN"; + data.flags |= SC_PIN_CMD_USE_PINPAD; + } + else + { + if(pin_value == NULL) + { + return SC_ERROR_INVALID_ARGUMENTS; + } + + data.pin1.data = pin_value; + data.pin1.len = strlen(pin_value); + } + + r = sc_pin_cmd(card, &data, &tries_left); + + if (r) + { + if (r == SC_ERROR_PIN_CODE_INCORRECT) + { + if (tries_left >= 0) + printf("Error %d attemps left.\n", tries_left); + else + printf("Wrong pin.\n"); + } + else + fprintf(stderr, "The pin can be verify: %s\n", sc_strerror(r)); + return -1; + } + printf("Pin correct.\n"); + return 0; +} + +static change_pin(sc_card_t *card, + int pin_reference, + char *pin_value1, + char *pin_value2) +{ + int r, tries_left = -1; + struct sc_pin_cmd_data data; + + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_CHANGE; + + data.pin_type = SC_AC_CHV; + + data.pin_reference = pin_reference; + + data.flags = SC_PIN_CMD_NEED_PADDING; + + if (card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) + { + printf("Please enter PIN on the reader's pin pad.\n"); + data.pin1.prompt = "Please enter PIN"; + data.flags |= SC_PIN_CMD_USE_PINPAD; + } + else + { + if(pin_value1 == NULL || pin_value2 == NULL) + { + return SC_ERROR_INVALID_ARGUMENTS; + } + + data.pin1.data = pin_value1; + data.pin1.len = strlen(pin_value1); + + data.pin2.data = pin_value2; + data.pin2.len = strlen(pin_value2); + + } + + r = sc_pin_cmd(card, &data, &tries_left); + + if (r) + { + if (r == SC_ERROR_PIN_CODE_INCORRECT) + { + if (tries_left >= 0) + printf("Error %d attemps left.\n", tries_left); + else + printf("Wrong pin.\n"); + } + else + fprintf(stderr, "Can't change pin: %s\n", + sc_strerror(r)); + return -1; + } + printf("Pin changed.\n"); + return 0; +} + +static debloque_pin(sc_card_t *card, + int pin_reference, + char *puk_value, + char *pin_value) +{ + int r, tries_left = -1; + struct sc_pin_cmd_data data; + + memset(&data, 0, sizeof(data)); + data.cmd = SC_PIN_CMD_UNBLOCK; + + data.pin_type = SC_AC_CHV; + + data.pin_reference = pin_reference; + + data.flags = SC_PIN_CMD_NEED_PADDING; + + if (card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) + { + printf("Please enter PIN on the reader's pin pad.\n"); + data.pin1.prompt = "Please enter PIN"; + data.flags |= SC_PIN_CMD_USE_PINPAD; + } + else + { + if(pin == NULL || puk == NULL) + { + return SC_ERROR_INVALID_ARGUMENTS; + } + + data.pin1.data = puk_value; + data.pin1.len = strlen(puk_value); + + data.pin2.data = pin_value; + data.pin2.len = strlen(pin_value); + + } + + r = sc_pin_cmd(card, &data, &tries_left); + + if (r) + { + if (r == SC_ERROR_PIN_CODE_INCORRECT) + { + if (tries_left >= 0) + printf("Error %d attemps left.\n", tries_left); + else + printf("Wrong pin.\n"); + } + else + fprintf(stderr, "Can't unblock pin: %s\n", + sc_strerror(r)); + return -1; + } + printf("Code debloque.\n"); + return 0; +} + +static int cert2der(X509 *cert, u8 **value) +{ + int len; + u8 *p; + len = i2d_X509(cert, NULL); + p = *value = (u8*)malloc(len); + i2d_X509(cert, &p); + return len; +} + +static int creation_fichier_cert(sc_card_t *card) +{ + int r; + int size; + sc_path_t path; + sc_file_t *file = NULL; + sc_context_t *ctx = card->ctx; + + sc_format_path("3F00", &path); + r = sc_select_file(card, &path, &file); + if(r) goto out; + + size = (file->size) - 32; + + if(file) + { + sc_file_free(file); + file = NULL; + } + + sc_format_path("0002", &path); + sc_ctx_suppress_errors_on(ctx); + r = sc_select_file(card, &path, NULL); + sc_ctx_suppress_errors_off(ctx); + if(r) + { + if(r != SC_ERROR_FILE_NOT_FOUND) goto out; + + file = sc_file_new(); + if(file == NULL) + { + fprintf(stderr, "memory error.\n"); + goto out; + } + + file->type = SC_FILE_TYPE_WORKING_EF; + file->ef_structure = SC_FILE_EF_TRANSPARENT; + file->shareable = 0; + + file->size = size; + + r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_NONE, 0); + if(r) goto out; + r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_CHV, 0); + if(r) goto out; + r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_CHV, 0); + if(r) goto out; + + file->path = path; + r = sc_create_file(card, file); + if(r) goto out; + } + +out: + if(file) + sc_file_free(file); + + return r; +} + +void usage(void) +{ +printf("Tools for westcos card.\n"); +printf("version %s.\n\n", version); +printf("\t -G Generate key 1536 default.\n"); +printf("\t -L [length] Key length 512,1024,1536.\n"); +printf("\t -i Install pin.\n"); +printf("\t -pin [value] Pin.\n"); +printf("\t -puk [value] Puk.\n"); +printf("\t -n Change pin (new pin in puk option).\n"); +printf("\t -u Unblock pin.\n"); +printf("\t -cert [file] Write certificate (in pem format).\n"); +printf("\t -F Finalize card "\ + "(!!! MANDATORY FOR SECURITY !!!).\n"); +printf("\t -r [n] Use reader number [n]"\ + " (default: autodetect).\n"); +printf("\t -gf [path] Read file [path].\n"); +printf("\t -pf [path] Write file [path].\n"); +printf("\t -v verbose.\n"); +printf("\t -h This message.\n"); +exit(0); +} + +int main(int argc, char *argv[]) +{ + int r; + int i = 1; + u8 *p; + int card_presente = 0; + sc_context_param_t ctx_param; + sc_reader_t *lecteur = NULL; + sc_card_t *card = NULL; + sc_context_t *ctx = NULL; + sc_file_t *file = NULL; + sc_path_t path; + RSA *rsa = RSA_new(); + BIGNUM *bn = BN_new(); + BIO *mem = BIO_new(BIO_s_mem()); + + if(rsa == NULL || bn == NULL || mem == NULL) + { + fprintf(stderr,"Not enougth memory.\n"); + goto out; + } + + while(i 1) + ctx->debug = verbose-1; + + if(no_lecteur == -1) + { + for(i = 0; i=0) + { + printf("card->name = %s\n", card->name); + if(strncmp(card->name, nom_card, strlen(nom_card)) == 0) + { + card_presente = 1; + break; + } + sc_disconnect_card(card,0); + card = NULL; + } + } + } + } + else + { + if(no_lecteur < sc_ctx_get_reader_count(ctx)) + { + lecteur = sc_ctx_get_reader(ctx, no_lecteur); + r = sc_connect_card(lecteur, 0, &card); + if(r>=0) + { + card_presente = 1; + } + else + { + sc_disconnect_card(card,0); + } + } + } + + if(!card_presente) goto out; + + sc_lock(card); + + sc_format_path("3F00", &path); + r = sc_select_file(card, &path, NULL); + if(r) goto out; + + if(install_pin) + { + sc_format_path("AAAA", &path); + sc_ctx_suppress_errors_on(ctx); + r = sc_select_file(card, &path, NULL); + sc_ctx_suppress_errors_off(ctx); + if(r) + { + if(r != SC_ERROR_FILE_NOT_FOUND) goto out; + + file = sc_file_new(); + if(file == NULL) + { + fprintf(stderr, "Not enougth memory.\n"); + goto out; + } + + file->type = SC_FILE_TYPE_INTERNAL_EF; + file->ef_structure = SC_FILE_EF_TRANSPARENT; + file->shareable = 0; + + file->id = 0xAAAA; + file->size = 37; + + r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_NONE, 0); + if(r) goto out; + r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_NONE, 0); + if(r) goto out; + r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_NONE, 0); + if(r) goto out; + + //sc_format_path("3F00AAAA", &(file->path)); + file->path = path; + r = sc_create_file(card, file); + if(r) goto out; + } + + if(pin != NULL) + { + sc_changekey_t ck; + struct sc_pin_cmd_pin pin_cmd; + + memset(&pin_cmd, 0, sizeof(pin_cmd)); + memset(&ck, 0, sizeof(ck)); + + memcpy(ck.key_template, "\x1e\x00\x00\x10", 4); + + pin_cmd.encoding = SC_PIN_ENCODING_GLP; + pin_cmd.len = strlen(pin); + pin_cmd.data = pin; + pin_cmd.max_length = 8; + + ck.new_key.key_len = sc_build_pin(ck.new_key.key_value, + sizeof(ck.new_key.key_value), &pin_cmd, 1); + if(ck.new_key.key_len<0) + goto out; + + r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck); + if(r) goto out; + } + + if(puk != NULL) + { + sc_changekey_t ck; + struct sc_pin_cmd_pin puk_cmd; + + memset(&puk_cmd, 0, sizeof(puk_cmd)); + memset(&ck, 0, sizeof(ck)); + + memcpy(ck.key_template, "\x1e\x00\x00\x20", 4); + + puk_cmd.encoding = SC_PIN_ENCODING_GLP; + puk_cmd.len = strlen(puk); + puk_cmd.data = puk; + puk_cmd.max_length = 8; + + ck.new_key.key_len = sc_build_pin(ck.new_key.key_value, + sizeof(ck.new_key.key_value), &puk_cmd, 1); + if(ck.new_key.key_len<0) + goto out; + + r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck); + if(r) goto out; + } + } + + if(new_pin) + { + if(change_pin(card, 0, pin, puk)) + printf("Wrong pin.\n"); + goto out; + } + + if(debloque) + { + if(debloque_pin(card, 0, puk, pin)) + printf("Error unblocking pin.\n"); + goto out; + } + + printf("verify pin.\n"); + { + if(verify_pin(card, 0, pin)) + { + printf("Wrong pin.\n"); + goto out; + } + } + + if(keylen) + { + int lg; + struct sc_pkcs15_pubkey key; + struct sc_pkcs15_pubkey_rsa *dst = &(key.u.rsa); + + memset(&key, 0, sizeof(key)); + key.algorithm = SC_ALGORITHM_RSA; + + printf("Generate key of length %d.\n", keylen); + + if(!BN_set_word(bn, RSA_F4) || + !RSA_generate_key_ex(rsa, keylen, bn, NULL)) + { + fprintf(stderr, + "RSA_generate_key_ex return %d\n", ERR_get_error()); + goto out; + } + + rsa->meth = RSA_PKCS1_SSLeay(); + + if(!i2d_RSAPrivateKey_bio(mem, rsa)) + { + fprintf(stderr, + "i2d_RSAPrivateKey_bio return %d\n", ERR_get_error()); + goto out; + } + + lg = BIO_get_mem_data(mem, &p); + + sc_format_path("0001", &path); + sc_ctx_suppress_errors_on(ctx); + r = sc_select_file(card, &path, NULL); + sc_ctx_suppress_errors_off(ctx); + if(r) + { + if(r != SC_ERROR_FILE_NOT_FOUND) goto out; + + file = sc_file_new(); + if(file == NULL) + { + fprintf(stderr, "Not enougth memory.\n"); + goto out; + } + + file->type = SC_FILE_TYPE_WORKING_EF; + file->ef_structure = SC_FILE_EF_TRANSPARENT; + file->shareable = 0; + + file->size = ((lg/4)+1)*4; + + r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_CHV, 0); + if(r) goto out; + r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_CHV, 0); + if(r) goto out; + r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_CHV, 0); + if(r) goto out; + + file->path = path; + + printf("File key creation %s, size %d.\n", file->path.value, + file->size); + + r = sc_create_file(card, file); + if(r) goto out; + } + else + { + if(!remplace) + { + fprintf(stderr, + "Key file already exist,"\ + " use -R to replace it.\n"); + goto out; + } + } + + printf("Private key length is %d\n", lg); + + printf("Write private key.\n"); + r = sc_update_binary(card,0,p,lg,0); + if(r<0) goto out; + printf("Private key correctly written.\n"); + + r = creation_fichier_cert(card); + if(r) goto out; + + if (!do_convert_bignum(&dst->modulus, rsa->n) + || !do_convert_bignum(&dst->exponent, rsa->e)) + goto out; + + r = sc_pkcs15_encode_pubkey(ctx, &key, &p, &lg); + if(r) goto out; + + printf("Public key length %d\n", lg); + + sc_format_path("3F000002", &path); + r = sc_select_file(card, &path, NULL); + if(r) goto out; + + printf("Write public key.\n"); + r = sc_update_binary(card,0,p,lg,0); + if(r<0) goto out; + printf("Public key correctly written.\n"); + + } + + if(cert) + { + BIO *bio; + X509 *xp; + + bio = BIO_new(BIO_s_file()); + if (BIO_read_filename(bio, cert) <= 0) + { + BIO_free(bio); + fprintf(stderr, "Can't open file %s.\n", cert); + goto out; + } + xp = PEM_read_bio_X509(bio, NULL, NULL, NULL); + BIO_free(bio); + if (xp == NULL) + { + print_openssl_erreur(); + goto out; + } + else + { + int lg = cert2der(xp, &p); + + sc_format_path("0002", &path); + r = sc_select_file(card, &path, NULL); + if(r) goto out; + + /* FIXME: verifier taille fichier compatible... */ + printf("Write certificate %s.\n", cert); + + r = sc_update_binary(card,0,p,lg,0); + if(r<0) + { + if(p) free(p); + goto out; + } + if(xp) X509_free(xp); + if(p) free(p); + + printf("Certificate correctly written.\n"); + } + } + + if(finalise) + { + int mode = SC_CARDCTRL_LIFECYCLE_USER; + + if(card->atr[10] != 0x82) + { + sc_format_path("0001", &path); + r = sc_select_file(card, &path, NULL); + if(r) + { + printf("This card don't have private key"\ + " and can't be finalize.\n"); + goto out; + } + printf("Finalize card...\n"); + if(sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL) || + sc_card_ctl(card, SC_CARDCTL_LIFECYCLE_SET, &mode)) + { + printf("Error finalizing card,"\ + " card isn't secure.\n"); + goto out; + } + } + printf("Card correctly finalized.\n"); + } + + if(get_filename) + { + FILE *fp; + u8 *b; + + if(file) + { + sc_file_free(file); + file = NULL; + } + + sc_format_path(get_filename, &path); + r = sc_select_file(card, &path, &file); + if(r) + { + printf("Error file not found.\n"); + goto out; + } + + b = (u8*)malloc(file->size); + if(b == NULL) + { + fprintf(stderr, "Not enougth memory.\n"); + goto out; + } + + r = sc_read_binary(card, 0, b, file->size, 0); + if(r<0) + { + printf("Error reading file.\n"); + goto out; + } + + fp = fopen(get_filename, "wb"); + fwrite(b, 1, file->size, fp); + fclose(fp); + + free(b); + } + + if(put_filename) + { + FILE *fp; + u8 *b; + + if(file) + { + sc_file_free(file); + file = NULL; + } + + sc_format_path(put_filename, &path); + r = sc_select_file(card, &path, &file); + if(r) + { + printf("File not found.\n"); + goto out; + } + + b = (u8*)malloc(file->size); + if(b == NULL) + { + fprintf(stderr, "Not enougth memory.\n"); + goto out; + } + + memset(b, 0, file->size); + + fp = fopen(put_filename, "rb"); + fread(b, 1, file->size, fp); + fclose(fp); + + r = sc_update_binary(card, 0, b, file->size, 0); + if(r<0) + { + free(b); + printf("Error writing file.\n"); + goto out; + } + + free(b); + } + +out: + + if(mem) + BIO_free(mem); + if(bn) + BN_free(bn); + if(rsa) + RSA_free(rsa); + + if(file) + sc_file_free(file); + + if (card) + { + sc_unlock(card); + sc_disconnect_card(card, 0); + } + + if (ctx) + sc_release_context(ctx); + +} + From d672fde4499fef4380cc3d8b88e496986687ec03 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 08:46:59 +0000 Subject: [PATCH 03/57] Remove sc_error and sc_ctx_suppress_errors_* in favor of sc_debug/fprintf git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3721 c6295689-39f2-0310-b995-f0e70906c6a9 --- etc/opensc.conf.in | 12 +--- src/libopensc/apdu.c | 22 +++---- src/libopensc/asn1.c | 32 +++++----- src/libopensc/card-akis.c | 12 ++-- src/libopensc/card-asepcos.c | 38 ++++++------ src/libopensc/card-atrust-acos.c | 8 +-- src/libopensc/card-belpic.c | 14 ++--- src/libopensc/card-cardos.c | 24 +++----- src/libopensc/card-default.c | 2 +- src/libopensc/card-entersafe.c | 6 +- src/libopensc/card-flex.c | 42 ++++++------- src/libopensc/card-gemsafeV1.c | 4 +- src/libopensc/card-gpk.c | 46 +++++++------- src/libopensc/card-incrypto34.c | 14 ++--- src/libopensc/card-jcop.c | 8 +-- src/libopensc/card-mcrd.c | 2 - src/libopensc/card-miocos.c | 14 ++--- src/libopensc/card-muscle.c | 28 ++++----- src/libopensc/card-oberthur.c | 28 ++++----- src/libopensc/card-openpgp.c | 16 +++-- src/libopensc/card-piv.c | 10 +-- src/libopensc/card-rtecp.c | 4 +- src/libopensc/card-rutoken.c | 14 ++--- src/libopensc/card-setcos.c | 12 ++-- src/libopensc/card-starcos.c | 10 +-- src/libopensc/card-tcos.c | 4 +- src/libopensc/card-westcos.c | 4 -- src/libopensc/card.c | 20 +++--- src/libopensc/ctbcs.c | 4 +- src/libopensc/ctx.c | 59 ++++++------------ src/libopensc/dir.c | 20 +++--- src/libopensc/iso7816.c | 26 ++++---- src/libopensc/libopensc.exports | 3 - src/libopensc/log.c | 21 ------- src/libopensc/log.h | 9 +-- src/libopensc/muscle.c | 24 ++------ src/libopensc/opensc.h | 15 +---- src/libopensc/p15card-helper.c | 10 +-- src/libopensc/p15emu-westcos.c | 8 --- src/libopensc/padding.c | 8 +-- src/libopensc/pkcs15-algo.c | 2 +- src/libopensc/pkcs15-atrust-acos.c | 4 -- src/libopensc/pkcs15-cache.c | 2 +- src/libopensc/pkcs15-cert.c | 2 +- src/libopensc/pkcs15-gemsafeGPK.c | 6 +- src/libopensc/pkcs15-gemsafeV1.c | 6 +- src/libopensc/pkcs15-infocamere.c | 10 +-- src/libopensc/pkcs15-openpgp.c | 4 +- src/libopensc/pkcs15-piv.c | 18 ++---- src/libopensc/pkcs15-postecert.c | 2 +- src/libopensc/pkcs15-prkey.c | 18 +++--- src/libopensc/pkcs15-pubkey.c | 10 +-- src/libopensc/pkcs15-sec.c | 10 +-- src/libopensc/pkcs15-starcert.c | 2 - src/libopensc/pkcs15-syn.c | 4 +- src/libopensc/pkcs15-tcos.c | 4 -- src/libopensc/pkcs15-wrap.c | 16 ++--- src/libopensc/pkcs15.c | 36 +++++------ src/libopensc/reader-ctapi.c | 36 +++++------ src/libopensc/reader-openct.c | 8 +-- src/libopensc/reader-pcsc.c | 12 ++-- src/libopensc/sc.c | 4 +- src/libopensc/sec.c | 4 +- src/libopensc/ui.c | 6 +- src/pkcs11/framework-pkcs15init.c | 2 - src/pkcs11/pkcs11-global.c | 4 +- src/pkcs15init/pkcs15-asepcos.c | 48 +++++++-------- src/pkcs15init/pkcs15-cardos.c | 18 +++--- src/pkcs15init/pkcs15-cflex.c | 22 +++---- src/pkcs15init/pkcs15-entersafe.c | 2 +- src/pkcs15init/pkcs15-gpk.c | 38 +++++------- src/pkcs15init/pkcs15-incrypto34.c | 12 ++-- src/pkcs15init/pkcs15-jcop.c | 6 +- src/pkcs15init/pkcs15-lib.c | 99 +++++++++++------------------- src/pkcs15init/pkcs15-miocos.c | 8 +-- src/pkcs15init/pkcs15-muscle.c | 12 ++-- src/pkcs15init/pkcs15-oberthur.c | 22 +++---- src/pkcs15init/pkcs15-rtecp.c | 4 +- src/pkcs15init/pkcs15-rutoken.c | 8 +-- src/pkcs15init/pkcs15-setcos.c | 16 ++--- src/pkcs15init/pkcs15-starcos.c | 6 -- src/pkcs15init/profile.c | 8 +-- src/tests/p15dump.c | 2 - src/tools/cryptoflex-tool.c | 4 -- src/tools/opensc-explorer.c | 6 -- src/tools/pkcs15-init.c | 13 ++-- src/tools/westcos-tool.c | 6 -- 87 files changed, 490 insertions(+), 759 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index e5e4654a..812c0411 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -16,20 +16,12 @@ app default { # The file to which debug output will be written # - # A special value of 'stdout' is recognized. - # Default: stdout + # Special values 'stdout' and 'stderr' are recognized. + # Default: stderr # # debug_file = /tmp/opensc-debug.log; # debug_file = "C:\Documents and Settings\All Users\Documents\opensc-debug.log"; - # The file to which errors will be written - # - # A special value of 'stderr' is recognized. - # Default: stderr - # - # error_file = /tmp/opensc-errors.log; - # error_file = "C:\Documents and Settings\All Users\Documents\opensc-errors.log"; - # PKCS#15 initialization / personalization # profiles directory for pkcs15-init. # Default: @pkgdatadir@ diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 4613ef6b..663b7c1e 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -122,7 +122,7 @@ static int sc_apdu2bytes(sc_context_t *ctx, const sc_apdu_t *apdu, if (apdu->lc > 255) { /* ... so if Lc is greater than 255 bytes * an error has occurred on a higher level */ - sc_error(ctx, "invalid Lc length for CASE 3 " + sc_debug(ctx, "invalid Lc length for CASE 3 " "extended APDU (need ENVELOPE)"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -215,7 +215,7 @@ int sc_apdu_set_resp(sc_context_t *ctx, sc_apdu_t *apdu, const u8 *buf, { if (len < 2) { /* no SW1 SW2 ... something went terrible wrong */ - sc_error(ctx, "invalid response: SW1 SW2 missing"); + sc_debug(ctx, "invalid response: SW1 SW2 missing"); return SC_ERROR_INTERNAL; } /* set the SW1 and SW2 status bytes (the last two bytes of @@ -273,7 +273,7 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) } else if ((apdu->cse & SC_APDU_EXT) != 0) { /* check if the card support extended APDUs */ if ((card->caps & SC_CARD_CAP_APDU_EXT) == 0) { - sc_error(card->ctx, "card doesn't support extended APDUs"); + sc_debug(card->ctx, "card doesn't support extended APDUs"); goto error; } /* length check for extended APDU */ @@ -325,12 +325,12 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) goto error; break; default: - sc_error(card->ctx, "Invalid APDU case %d\n", apdu->cse); + sc_debug(card->ctx, "Invalid APDU case %d\n", apdu->cse); return SC_ERROR_INVALID_ARGUMENTS; } return SC_SUCCESS; error: - sc_error(card->ctx, "Invalid Case %d %s APDU:\n" + sc_debug(card->ctx, "Invalid Case %d %s APDU:\n" "cse=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%lu le=%lu\n" "resp=%p resplen=%lu data=%p datalen=%lu", apdu->cse & SC_APDU_SHORT_MASK, @@ -391,7 +391,7 @@ static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu) return SC_ERROR_NOT_SUPPORTED; r = card->reader->ops->transmit(card->reader, card->slot, apdu); if (r != 0) { - sc_error(ctx, "unable to transmit APDU"); + sc_debug(ctx, "unable to transmit APDU"); return r; } /* ok, the APDU was successfully transmitted. Now we have two @@ -416,7 +416,7 @@ static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu) /* re-transmit the APDU with new Le length */ r = card->reader->ops->transmit(card->reader, card->slot, apdu); if (r != SC_SUCCESS) { - sc_error(ctx, "unable to transmit APDU"); + sc_debug(ctx, "unable to transmit APDU"); return r; } } else { @@ -451,7 +451,7 @@ static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu) if (card->ops->get_response == NULL) { /* this should _never_ happen */ - sc_error(ctx, "no GET RESPONSE command\n"); + sc_debug(ctx, "no GET RESPONSE command\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -525,7 +525,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) r = sc_lock(card); /* acquire card lock*/ if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to acquire lock"); + sc_debug(card->ctx, "unable to acquire lock"); return r; } @@ -566,7 +566,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) r = sc_check_apdu(card, &tapdu); if (r != SC_SUCCESS) { - sc_error(card->ctx, "inconsistent APDU while chaining"); + sc_debug(card->ctx, "inconsistent APDU while chaining"); break; } @@ -593,7 +593,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu) r = do_single_transmit(card, apdu); /* all done => release lock */ if (sc_unlock(card) != SC_SUCCESS) - sc_error(card->ctx, "sc_unlock failed"); + sc_debug(card->ctx, "sc_unlock failed"); return r; } diff --git a/src/libopensc/asn1.c b/src/libopensc/asn1.c index 5eaf8ac9..49af637c 100644 --- a/src/libopensc/asn1.c +++ b/src/libopensc/asn1.c @@ -307,7 +307,7 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf, if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS) return NULL; if (left < (size_t)(p - buf)) { - sc_error(ctx, "invalid TLV object\n"); + sc_debug(ctx, "invalid TLV object\n"); return NULL; } left -= (p - buf); @@ -327,7 +327,7 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf, } /* otherwise continue reading tags */ if (left < taglen) { - sc_error(ctx, "invalid TLV object\n"); + sc_debug(ctx, "invalid TLV object\n"); return NULL; } left -= taglen; @@ -373,7 +373,7 @@ const u8 *sc_asn1_skip_tag(sc_context_t *ctx, const u8 ** buf, size_t *buflen, return NULL; len -= (p - *buf); /* header size */ if (taglen > len) { - sc_error(ctx, "too long ASN.1 object (size %d while only %d available)\n", + sc_debug(ctx, "too long ASN.1 object (size %d while only %d available)\n", taglen, len); return NULL; } @@ -723,7 +723,7 @@ static int asn1_write_element(sc_context_t *ctx, unsigned int tag, t = tag & 0x1F; if (t != (tag & SC_ASN1_TAG_MASK)) { - sc_error(ctx, "Long tags not supported\n"); + sc_debug(ctx, "Long tags not supported\n"); return SC_ERROR_INVALID_ARGUMENTS; } switch (tag & SC_ASN1_CLASS_MASK) { @@ -989,7 +989,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, case SC_ASN1_BOOLEAN: if (parm != NULL) { if (objlen != 1) { - sc_error(ctx, "invalid ASN.1 object length: %d\n", objlen); + sc_debug(ctx, "invalid ASN.1 object length: %d\n", objlen); r = SC_ERROR_INVALID_ASN1_OBJECT; } else *((int *) parm) = obj[0] ? 1 : 0; @@ -1133,11 +1133,11 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry, r = callback_func(ctx, entry->arg, obj, objlen, depth); break; default: - sc_error(ctx, "invalid ASN.1 type: %d\n", entry->type); + sc_debug(ctx, "invalid ASN.1 type: %d\n", entry->type); return SC_ERROR_INVALID_ASN1_OBJECT; } if (r) { - sc_error(ctx, "decoding of ASN.1 object '%s' failed: %s\n", entry->name, + sc_debug(ctx, "decoding of ASN.1 object '%s' failed: %s\n", entry->name, sc_strerror(r)); return r; } @@ -1167,7 +1167,7 @@ static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1, * to complain about */ if (asn1->name == NULL) return 0; - sc_error(ctx, "End of ASN.1 stream, " + sc_debug(ctx, "End of ASN.1 stream, " "non-optional field \"%s\" not found\n", asn1->name); return SC_ERROR_ASN1_OBJECT_NOT_FOUND; @@ -1204,7 +1204,7 @@ static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1, continue; if (entry->flags & SC_ASN1_OPTIONAL) continue; - sc_error(ctx, "mandatory ASN.1 object '%s' not found\n", entry->name); + sc_debug(ctx, "mandatory ASN.1 object '%s' not found\n", entry->name); if (ctx->debug && left) { u8 line[128], *linep = line; size_t i; @@ -1281,7 +1281,7 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr while (list->name != NULL) { if (list->flags & SC_ASN1_PRESENT) { if (choice) { - sc_error(ctx, + sc_debug(ctx, "ASN.1 problem: more than " "one CHOICE when encoding %s: " "%s and %s both present\n", @@ -1300,7 +1300,7 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr } if (entry->type != SC_ASN1_NULL && parm == NULL) { - sc_error(ctx, "unexpected parm == NULL\n"); + sc_debug(ctx, "unexpected parm == NULL\n"); return SC_ERROR_INVALID_ASN1_OBJECT; } @@ -1396,11 +1396,11 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr r = callback_func(ctx, entry->arg, &buf, &buflen, depth); break; default: - sc_error(ctx, "invalid ASN.1 type: %d\n", entry->type); + sc_debug(ctx, "invalid ASN.1 type: %d\n", entry->type); return SC_ERROR_INVALID_ASN1_OBJECT; } if (r) { - sc_error(ctx, "encoding of ASN.1 object '%s' failed: %s\n", entry->name, + sc_debug(ctx, "encoding of ASN.1 object '%s' failed: %s\n", entry->name, sc_strerror(r)); if (buf) free(buf); @@ -1430,13 +1430,13 @@ no_object: r = asn1_write_element(ctx, entry->tag, buf, buflen, obj, objlen); if (r) - sc_error(ctx, "error writing ASN.1 tag and length: %s\n", + sc_debug(ctx, "error writing ASN.1 tag and length: %s\n", sc_strerror(r)); } else if (!(entry->flags & SC_ASN1_PRESENT)) { - sc_error(ctx, "cannot encode non-optional ASN.1 object: not given by caller\n"); + sc_debug(ctx, "cannot encode non-optional ASN.1 object: not given by caller\n"); r = SC_ERROR_INVALID_ASN1_OBJECT; } else { - sc_error(ctx, "cannot encode empty non-optional ASN.1 object\n"); + sc_debug(ctx, "cannot encode empty non-optional ASN.1 object\n"); r = SC_ERROR_INVALID_ASN1_OBJECT; } if (buf) diff --git a/src/libopensc/card-akis.c b/src/libopensc/card-akis.c index 38e5bee5..3aa0548c 100644 --- a/src/libopensc/card-akis.c +++ b/src/libopensc/card-akis.c @@ -168,7 +168,7 @@ akis_list_files(sc_card_t *card, u8 *buf, size_t buflen) while (left > 19) { if (p[0] != 0x2f && p[0] != 0x3d) { - sc_error(card->ctx, "Malformatted list reply %02x", p[0]); + sc_debug(card->ctx, "Malformatted list reply %02x", p[0]); return SC_ERROR_INTERNAL; } if (buflen >= 2) { @@ -202,7 +202,7 @@ akis_process_fci(sc_card_t *card, sc_file_t *file, */ p = sc_asn1_find_tag(card->ctx, buf, buflen, 0x90, &len); if (p == NULL) { - sc_error(card->ctx, "Security tag missing"); + sc_debug(card->ctx, "Security tag missing"); return SC_ERROR_INTERNAL; } perms = p[0]; @@ -272,7 +272,7 @@ akis_create_file(sc_card_t *card, sc_file_t *file) type = 0x45; break; default: - sc_error(card->ctx, "This EF structure is not supported yet"); + sc_debug(card->ctx, "This EF structure is not supported yet"); return SC_ERROR_NOT_SUPPORTED; } apdu.p1 = type; @@ -284,7 +284,7 @@ akis_create_file(sc_card_t *card, sc_file_t *file) } else if (file->type == SC_FILE_TYPE_DF) { apdu.ins = 0x10; } else { - sc_error(card->ctx, "Unknown file type"); + sc_debug(card->ctx, "Unknown file type"); return SC_ERROR_NOT_SUPPORTED; } @@ -317,7 +317,7 @@ akis_delete_file(sc_card_t *card, const sc_path_t *path) type = 0x08; break; default: - sc_error(card->ctx, "File type has to be FID or PATH"); + sc_debug(card->ctx, "File type has to be FID or PATH"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x16, type, 0x00); @@ -372,7 +372,7 @@ akis_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left return r; } - sc_error(card->ctx, "Other pin cmds not supported yet"); + sc_debug(card->ctx, "Other pin cmds not supported yet"); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 71007f7a..ead84585 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -64,7 +64,7 @@ static int asepcos_select_asepcos_applet(sc_card_t *card) r = sc_select_file(card, &tpath, NULL); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to select ASEPCOS applet"); + sc_debug(card->ctx, "unable to select ASEPCOS applet"); return r; } @@ -165,7 +165,7 @@ static int asepcos_parse_sec_attr(sc_card_t *card, sc_file_t *file, const u8 *bu while (len != 0) { unsigned int amode, tlen = 3; if (len < 5 && p[0] != 0x80 && p[1] != 0x01) { - sc_error(card->ctx, "invalid access mode encoding"); + sc_debug(card->ctx, "invalid access mode encoding"); return SC_ERROR_INTERNAL; } amode = p[2]; @@ -192,7 +192,7 @@ static int asepcos_parse_sec_attr(sc_card_t *card, sc_file_t *file, const u8 *bu return r; tlen += 2 + p[4]; /* FIXME */ } else { - sc_error(card->ctx, "invalid security condition"); + sc_debug(card->ctx, "invalid security condition"); return SC_ERROR_INTERNAL; } p += tlen; @@ -306,7 +306,7 @@ static int asepcos_select_file(sc_card_t *card, const sc_path_t *in_path, if (r == SC_SUCCESS && file != NULL) { r = asepcos_parse_sec_attr(card, *file, (*file)->sec_attr, (*file)->sec_attr_len); if (r != SC_SUCCESS) - sc_error(card->ctx, "error parsing security attributes"); + sc_debug(card->ctx, "error parsing security attributes"); } SC_FUNC_RETURN(card->ctx, 1, r); } @@ -482,7 +482,7 @@ static int asepcos_set_security_attributes(sc_card_t *card, sc_file_t *file) *p++ = (st.fileid >> 8 ) & 0xff; *p++ = st.fileid & 0xff; } else { - sc_error(card->ctx, "unknow auth method: '%d'", ent->method); + sc_debug(card->ctx, "unknow auth method: '%d'", ent->method); return SC_ERROR_INTERNAL; } } @@ -550,7 +550,7 @@ static int asepcos_compute_signature(sc_card_t *card, const u8 *data, size_t dat r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { - sc_error(card->ctx, "error creating signature"); + sc_debug(card->ctx, "error creating signature"); return sc_check_sw(card, apdu.sw1, apdu.sw2); } @@ -628,7 +628,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) /* set security attributes */ r = asepcos_set_security_attributes(card, file); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to set security attributes"); + sc_debug(card->ctx, "unable to set security attributes"); return r; } return SC_SUCCESS; @@ -674,7 +674,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) /* set security attributes */ r = asepcos_set_security_attributes(card, file); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to set security attributes"); + sc_debug(card->ctx, "unable to set security attributes"); return r; } return asepcos_activate_file(card, file->id, 1); @@ -701,7 +701,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file) /* set security attributes */ r = asepcos_set_security_attributes(card, file); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to set security attributes"); + sc_debug(card->ctx, "unable to set security attributes"); return r; } return asepcos_activate_file(card, file->id, 1); @@ -735,7 +735,7 @@ static int asepcos_list_files(sc_card_t *card, u8 *buf, size_t blen) return r; if (tfile->prop_attr_len != 6 || tfile->prop_attr == NULL) { sc_file_free(tfile); - sc_error(card->ctx, "unable to parse proprietary FCI attributes"); + sc_debug(card->ctx, "unable to parse proprietary FCI attributes"); return SC_ERROR_INTERNAL; } dfFID = (tfile->prop_attr[2] << 8) | tfile->prop_attr[3]; @@ -1013,7 +1013,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, return SC_ERROR_INVALID_ARGUMENTS; /* check PIN length */ if (pdata->pin1.len < 4 || pdata->pin1.len > 16) { - sc_error(card->ctx, "invalid PIN1 length"); + sc_debug(card->ctx, "invalid PIN1 length"); return SC_ERROR_INVALID_PIN_LENGTH; } @@ -1025,11 +1025,11 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) - sc_error(card->ctx, "APDU transmit failed"); + sc_debug(card->ctx, "APDU transmit failed"); break; case SC_PIN_CMD_CHANGE: if (pdata->pin2.len < 4 || pdata->pin2.len > 16) { - sc_error(card->ctx, "invalid PIN2 length"); + sc_debug(card->ctx, "invalid PIN2 length"); return SC_ERROR_INVALID_PIN_LENGTH; } /* 1. step: verify the old pin */ @@ -1038,7 +1038,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) { - sc_error(card->ctx, "APDU transmit failed"); + sc_debug(card->ctx, "APDU transmit failed"); break; } if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { @@ -1052,12 +1052,12 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) - sc_error(card->ctx, "APDU transmit failed"); + sc_debug(card->ctx, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); break; case SC_PIN_CMD_UNBLOCK: if (pdata->pin2.len < 4 || pdata->pin2.len > 16) { - sc_error(card->ctx, "invalid PIN2 length"); + sc_debug(card->ctx, "invalid PIN2 length"); return SC_ERROR_INVALID_PIN_LENGTH; } /* 1. step: verify the puk */ @@ -1066,7 +1066,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) { - sc_error(card->ctx, "APDU transmit failed"); + sc_debug(card->ctx, "APDU transmit failed"); break; } /* 2, step: unblock and change the pin */ @@ -1075,13 +1075,13 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata, break; r = sc_transmit_apdu(card, &apdu); if (r != SC_SUCCESS) { - sc_error(card->ctx, "APDU transmit failed"); + sc_debug(card->ctx, "APDU transmit failed"); break; } r = sc_check_sw(card, apdu.sw1, apdu.sw2); break; default: - sc_error(card->ctx, "error: unknow cmd type"); + sc_debug(card->ctx, "error: unknow cmd type"); return SC_ERROR_INTERNAL; } /* Clear the buffer - it may contain pins */ diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index 1c45ad07..e19991ae 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -624,11 +624,9 @@ static int atrust_acos_set_security_env(struct sc_card *card, apdu.datalen = p - sbuf; apdu.lc = p - sbuf; apdu.le = 0; - /* suppress errors, as don't know whether to use + /* we don't know whether to use * COMPUTE SIGNATURE or INTERNAL AUTHENTICATE */ - sc_ctx_suppress_errors_on(card->ctx); r = sc_transmit_apdu(card, &apdu); - sc_ctx_suppress_errors_off(card->ctx); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { ex_data->fix_digestInfo = 0; @@ -816,7 +814,7 @@ static int atrust_acos_check_sw(struct sc_card *card, unsigned int sw1, return SC_NO_ERROR; if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 ) { - sc_error(card->ctx, "Verification failed (remaining tries: %d)\n", + sc_debug(card->ctx, "Verification failed (remaining tries: %d)\n", (sw2 & 0x0f)); return SC_ERROR_PIN_CODE_INCORRECT; } @@ -889,9 +887,7 @@ static int atrust_acos_logout(struct sc_card *card) apdu.datalen = 2; apdu.resplen = 0; - sc_ctx_suppress_errors_on(card->ctx); r = sc_transmit_apdu(card, &apdu); - sc_ctx_suppress_errors_off(card->ctx); SC_TEST_RET(card->ctx, r, "APDU re-transmit failed"); if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85) diff --git a/src/libopensc/card-belpic.c b/src/libopensc/card-belpic.c index d936e4c4..99bef3e1 100644 --- a/src/libopensc/card-belpic.c +++ b/src/libopensc/card-belpic.c @@ -286,7 +286,7 @@ struct pcsc_slot_data { SCARDHANDLE pcsc_card; }; /* comes from reader-pcsc.c */ #define GET_SLOT_DATA(r) ((struct pcsc_slot_data *) (r)->drv_data) -#define PCSC_ERROR(ctx, desc, rv) sc_error(ctx, desc ": %lx\n", rv); +#define PCSC_ERROR(ctx, desc, rv) sc_debug(ctx, desc ": %lx\n", rv); #endif /* BELPIC_PIN_PAD */ @@ -1035,7 +1035,7 @@ static int belpic_init(sc_card_t *card) #ifdef HAVE_GUI r = scgui_init(); if (r != 0) - sc_error(card->ctx, "scgui_init() returned error %d\n", i); + sc_debug(card->ctx, "scgui_init() returned error %d\n", i); #endif #ifdef BELPIC_PIN_PAD @@ -1209,7 +1209,7 @@ static int belpic_pp_verify(sc_card_t *card, SCR_Card * scr_card, if (r1 == SCGUI_CANCEL) return r; else if (r1 != SCGUI_OK) { - sc_error(card->ctx, "scgui_ask_message returned %d\n", r1); + sc_debug(card->ctx, "scgui_ask_message returned %d\n", r1); return SC_ERROR_INTERNAL; } } else @@ -1272,7 +1272,7 @@ static int belpic_pp_change(sc_card_t *card, SCR_Card * scr_card, if (r1 == SCGUI_CANCEL) return r; else if (r1 != SCGUI_OK) { - sc_error(card->ctx, "scgui_ask_message returned %d\n", r1); + sc_debug(card->ctx, "scgui_ask_message returned %d\n", r1); return SC_ERROR_INTERNAL; } } @@ -1417,7 +1417,7 @@ static int belpic_askpin_verify(sc_card_t *card, int pin_usage) if (r1 == SCGUI_CANCEL) return r; else if (r1 != SCGUI_OK) { - sc_error(card->ctx, "scgui_ask_message returned %d\n", r1); + sc_debug(card->ctx, "scgui_ask_message returned %d\n", r1); return SC_ERROR_INTERNAL; } @@ -1470,7 +1470,7 @@ static int belpic_set_security_env(sc_card_t *card, else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_MD5) sbuf[2] = 0x04; else { - sc_error(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n", + sc_debug(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n", env->algorithm_flags); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1506,7 +1506,7 @@ static int belpic_set_security_env(sc_card_t *card, #ifdef HAVE_GUI r = belpic_askpin_verify(card, SCR_USAGE_SIGN); if (r != 0 && r != SC_ERROR_KEYPAD_CANCELLED) - sc_error(card->ctx, "Verify PIN in SET command returned %d\n", r); + sc_debug(card->ctx, "Verify PIN in SET command returned %d\n", r); else sc_debug(card->ctx, "Verify PIN in SET command returned %d\n", r); #else diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index c4789e3c..b6f0924e 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -255,13 +255,13 @@ static int cardos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) for (i = 0; i < err_count; i++) { if (cardos_errors[i].SWs == ((sw1 << 8) | sw2)) { if ( cardos_errors[i].errorstr ) - sc_error(card->ctx, "%s\n", + sc_debug(card->ctx, "%s\n", cardos_errors[i].errorstr); return cardos_errors[i].errorno; } } - sc_error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); + sc_debug(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); return SC_ERROR_CARD_CMD_FAILED; } @@ -291,7 +291,7 @@ get_next_part: SC_TEST_RET(card->ctx, r, "DIRECTORY command returned error"); if (apdu.resplen > 256) { - sc_error(card->ctx, "directory listing > 256 bytes, cutting"); + sc_debug(card->ctx, "directory listing > 256 bytes, cutting"); r = 256; } @@ -301,7 +301,7 @@ get_next_part: /* is there a file informatin block (0x6f) ? */ p = sc_asn1_find_tag(card->ctx, p, len, 0x6f, &tlen); if (p == NULL) { - sc_error(card->ctx, "directory tag missing"); + sc_debug(card->ctx, "directory tag missing"); return SC_ERROR_INTERNAL; } if (tlen == 0) @@ -309,7 +309,7 @@ get_next_part: break; q = sc_asn1_find_tag(card->ctx, p, tlen, 0x86, &ilen); if (q == NULL || ilen != 2) { - sc_error(card->ctx, "error parsing file id TLV object"); + sc_debug(card->ctx, "error parsing file id TLV object"); return SC_ERROR_INTERNAL; } /* put file id in buf */ @@ -451,7 +451,7 @@ static int cardos_acl_to_bytes(sc_card_t *card, const sc_file_t *file, else byte = acl_to_byte(sc_file_get_acl_entry(file, idx[i])); if (byte < 0) { - sc_error(card->ctx, "Invalid ACL\n"); + sc_debug(card->ctx, "Invalid ACL\n"); return SC_ERROR_INVALID_ARGUMENTS; } buf[i] = byte; @@ -581,7 +581,7 @@ static int cardos_construct_fcp(sc_card_t *card, const sc_file_t *file, buf[4] |= (u8) file->record_count; break; default: - sc_error(card->ctx, "unknown EF type: %u", file->type); + sc_debug(card->ctx, "unknown EF type: %u", file->type); return SC_ERROR_INVALID_ARGUMENTS; } if (file->ef_structure == SC_FILE_EF_CYCLIC || @@ -657,7 +657,7 @@ static int cardos_create_file(sc_card_t *card, sc_file_t *file) r = cardos_construct_fcp(card, file, sbuf, &len); if (r < 0) { - sc_error(card->ctx, "unable to create FCP"); + sc_debug(card->ctx, "unable to create FCP"); return r; } @@ -719,7 +719,7 @@ cardos_set_security_env(sc_card_t *card, if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { - sc_error(card->ctx, "No or invalid key reference\n"); + sc_debug(card->ctx, "No or invalid key reference\n"); return SC_ERROR_INVALID_ARGUMENTS; } key_id = env->key_ref[0]; @@ -822,9 +822,7 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, if (!(card->caps & (SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED | SC_CARD_CAP_ONLY_RAW_HASH))) { if (ctx->debug >= 3) sc_debug(ctx, "trying RSA_PURE_SIG (padded DigestInfo)\n"); - sc_ctx_suppress_errors_on(ctx); r = do_compute_signature(card, data, datalen, out, outlen); - sc_ctx_suppress_errors_off(ctx); if (r >= SC_SUCCESS) SC_FUNC_RETURN(ctx, 4, r); } @@ -849,9 +847,7 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, if (!(card->caps & (SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED | SC_CARD_CAP_ONLY_RAW_HASH)) || card->caps & SC_CARD_CAP_ONLY_RAW_HASH ) { if (ctx->debug >= 3) sc_debug(ctx, "trying to sign raw hash value with prefix\n"); - sc_ctx_suppress_errors_on(ctx); r = do_compute_signature(card, buf, tmp_len, out, outlen); - sc_ctx_suppress_errors_off(ctx); if (r >= SC_SUCCESS) SC_FUNC_RETURN(ctx, 4, r); } @@ -906,7 +902,7 @@ cardos_lifecycle_get(sc_card_t *card, int *mode) *mode = SC_CARDCTRL_LIFECYCLE_OTHER; break; default: - sc_error(card->ctx, "Unknown lifecycle byte %d", rbuf[0]); + sc_debug(card->ctx, "Unknown lifecycle byte %d", rbuf[0]); r = SC_ERROR_INTERNAL; } diff --git a/src/libopensc/card-default.c b/src/libopensc/card-default.c index 1c007305..ab7083fd 100644 --- a/src/libopensc/card-default.c +++ b/src/libopensc/card-default.c @@ -110,7 +110,7 @@ static int default_init(sc_card_t *card) card->drv_data = NULL; r = autodetect_class(card); if (r) { - sc_error(card->ctx, "unable to determine the right class byte\n"); + sc_debug(card->ctx, "unable to determine the right class byte\n"); return SC_ERROR_INVALID_CARD; } diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index e6c5e891..49c872d4 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -196,18 +196,18 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL); if(!EVP_EncryptUpdate(&ctx,buff,&apdu->lc,buff,buffsize)){ - sc_error(card->ctx, "entersafe encryption error."); + sc_debug(card->ctx, "entersafe encryption error."); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL); } if (!EVP_CIPHER_CTX_cleanup(&ctx)){ - sc_error(card->ctx, "entersafe encryption error."); + sc_debug(card->ctx, "entersafe encryption error."); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL); } if(apdu->lc!=buffsize) { - sc_error(card->ctx, "entersafe build cipher apdu failed."); + sc_debug(card->ctx, "entersafe build cipher apdu failed."); SC_FUNC_RETURN(card->ctx, 3, SC_ERROR_INTERNAL); } diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index 10e7fd85..2a932b2d 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -317,7 +317,7 @@ cryptoflex_process_file_attrs(sc_card_t *card, sc_file_t *file, file->type = SC_FILE_TYPE_DF; break; default: - sc_error(ctx, "invalid file type: 0x%02X\n", *p); + sc_debug(ctx, "invalid file type: 0x%02X\n", *p); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } p += 2; @@ -386,7 +386,7 @@ cyberflex_process_file_attrs(sc_card_t *card, sc_file_t *file, file->type = SC_FILE_TYPE_WORKING_EF; break; default: - sc_error(ctx, "invalid file type: 0x%02X\n", *p); + sc_debug(ctx, "invalid file type: 0x%02X\n", *p); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } @@ -436,7 +436,7 @@ cyberflex_process_file_attrs(sc_card_t *card, sc_file_t *file, #endif break; default: - sc_error(ctx, "invalid file type: 0x%02X\n", *p); + sc_debug(ctx, "invalid file type: 0x%02X\n", *p); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } switch (file->ef_structure) { @@ -571,7 +571,7 @@ static int select_file_id(sc_card_t *card, const u8 *buf, size_t buflen, if (apdu.resplen < 14) return SC_ERROR_UNKNOWN_DATA_RECEIVED; if (apdu.resp[0] == 0x6F) { - sc_error(card->ctx, "unsupported: card returned FCI\n"); + sc_debug(card->ctx, "unsupported: card returned FCI\n"); return SC_ERROR_UNKNOWN_DATA_RECEIVED; /* FIXME */ } file = sc_file_new(); @@ -672,7 +672,7 @@ static int cryptoflex_list_files(sc_card_t *card, u8 *buf, size_t buflen) if (r) return r; if (apdu.resplen != 4) { - sc_error(card->ctx, "expected 4 bytes, got %d.\n", apdu.resplen); + sc_debug(card->ctx, "expected 4 bytes, got %d.\n", apdu.resplen); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } memcpy(buf, rbuf + 2, 2); @@ -707,7 +707,7 @@ static int cyberflex_list_files(sc_card_t *card, u8 *buf, size_t buflen) if (r) return r; if (apdu.resplen != 6) { - sc_error(card->ctx, "expected 6 bytes, got %d.\n", apdu.resplen); + sc_debug(card->ctx, "expected 6 bytes, got %d.\n", apdu.resplen); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } memcpy(buf, rbuf + 4, 2); @@ -725,7 +725,7 @@ static int flex_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, 1); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { - sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00); @@ -810,7 +810,7 @@ cryptoflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file, p[6] = 0x06; break; default: - sc_error(card->ctx, "Invalid EF structure\n"); + sc_debug(card->ctx, "Invalid EF structure\n"); return -1; } p[7] = 0xFF; /* allow Decrease and Increase */ @@ -906,7 +906,7 @@ cyberflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file, p[4] = 0x1D; break; default: - sc_error(card->ctx, "Invalid EF structure\n"); + sc_debug(card->ctx, "Invalid EF structure\n"); return -1; } p[5] = 0x01; /* status?? */ @@ -945,7 +945,7 @@ static int flex_create_file(sc_card_t *card, sc_file_t *file) * abstracting the Cryptoflex/Cyberflex differences */ r = card->ops->construct_fci(card, file, sbuf, &sendlen); if (r) { - sc_error(card->ctx, "File structure encoding failed.\n"); + sc_debug(card->ctx, "File structure encoding failed.\n"); return SC_ERROR_INVALID_ARGUMENTS; } if (file->type != SC_FILE_TYPE_DF && file->ef_structure != SC_FILE_EF_TRANSPARENT) @@ -982,33 +982,33 @@ static int flex_set_security_env(sc_card_t *card, if (env->operation != SC_SEC_OPERATION_SIGN && env->operation != SC_SEC_OPERATION_DECIPHER) { - sc_error(card->ctx, "Invalid crypto operation supplied.\n"); + sc_debug(card->ctx, "Invalid crypto operation supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->algorithm != SC_ALGORITHM_RSA) { - sc_error(card->ctx, "Invalid crypto algorithm supplied.\n"); + sc_debug(card->ctx, "Invalid crypto algorithm supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } if ((env->algorithm_flags & SC_ALGORITHM_RSA_PADS) || (env->algorithm_flags & SC_ALGORITHM_RSA_HASHES)) { - sc_error(card->ctx, "Card supports only raw RSA.\n"); + sc_debug(card->ctx, "Card supports only raw RSA.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { if (env->key_ref_len != 1 || (env->key_ref[0] != 0 && env->key_ref[0] != 1)) { - sc_error(card->ctx, "Invalid key reference supplied.\n"); + sc_debug(card->ctx, "Invalid key reference supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } prv->rsa_key_ref = env->key_ref[0]; } if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) { - sc_error(card->ctx, "Algorithm reference not supported.\n"); + sc_debug(card->ctx, "Algorithm reference not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) if (memcmp(env->file_ref.value, "\x00\x12", 2) != 0) { - sc_error(card->ctx, "File reference is not 0012.\n"); + sc_debug(card->ctx, "File reference is not 0012.\n"); return SC_ERROR_NOT_SUPPORTED; } return 0; @@ -1030,11 +1030,11 @@ cryptoflex_compute_signature(sc_card_t *card, const u8 *data, size_t i, i2; if (data_len != 64 && data_len != 96 && data_len != 128 && data_len != 256) { - sc_error(card->ctx, "Illegal input length: %d\n", data_len); + sc_debug(card->ctx, "Illegal input length: %d\n", data_len); return SC_ERROR_INVALID_ARGUMENTS; } if (outlen < data_len) { - sc_error(card->ctx, "Output buffer too small.\n"); + sc_debug(card->ctx, "Output buffer too small.\n"); return SC_ERROR_BUFFER_TOO_SMALL; } sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, prv->rsa_key_ref); @@ -1090,13 +1090,13 @@ cyberflex_compute_signature(sc_card_t *card, const u8 *data, case 96: alg_id = 0xC6; break; case 128: alg_id = 0xC8; break; default: - sc_error(card->ctx, "Illegal input length: %d\n", data_len); + sc_debug(card->ctx, "Illegal input length: %d\n", data_len); return SC_ERROR_INVALID_ARGUMENTS; } key_id = prv->rsa_key_ref + 1; /* Why? */ if (outlen < data_len) { - sc_error(card->ctx, "Output buffer too small.\n"); + sc_debug(card->ctx, "Output buffer too small.\n"); return SC_ERROR_BUFFER_TOO_SMALL; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x88, alg_id, key_id); @@ -1163,7 +1163,7 @@ static int flex_generate_key(sc_card_t *card, struct sc_cardctl_cryptoflex_genke case 1024: p2 = 0x80; break; case 2048: p2 = 0x00; break; default: - sc_error(card->ctx, "Illegal key length: %d\n", data->key_bits); + sc_debug(card->ctx, "Illegal key length: %d\n", data->key_bits); return SC_ERROR_INVALID_ARGUMENTS; } diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index d80cd0fe..d0ef7a22 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -586,7 +586,7 @@ static int gemsafe_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, /* Call the reader driver to collect * the PIN and pass on the APDU to the card */ if (data->pin1.offset == 0) { - sc_error(card->ctx, + sc_debug(card->ctx, "Card driver didn't set PIN offset"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -598,7 +598,7 @@ static int gemsafe_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, data); /* sw1/sw2 filled in by reader driver */ } else { - sc_error(card->ctx, + sc_debug(card->ctx, "Card reader driver does not support " "PIN entry through reader key pad"); r = SC_ERROR_NOT_SUPPORTED; diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 846de56a..7a80fb72 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -232,23 +232,23 @@ gpk_check_sw(sc_card_t *card, u8 sw1, u8 sw2) unsigned short int sw = (sw1 << 8) | sw2; if ((sw & 0xFFF0) == 0x63C0) { - sc_error(card->ctx, "wrong PIN, %u tries left\n", sw&0xf); + sc_debug(card->ctx, "wrong PIN, %u tries left\n", sw&0xf); return SC_ERROR_PIN_CODE_INCORRECT; } switch (sw) { case 0x6400: - sc_error(card->ctx, "wrong crypto context\n"); + sc_debug(card->ctx, "wrong crypto context\n"); return SC_ERROR_OBJECT_NOT_VALID; /* XXX ??? */ /* The following are handled by iso7816_check_sw * but all return SC_ERROR_UNKNOWN_DATA_RECEIVED * XXX: fix in the iso driver? */ case 0x6983: - sc_error(card->ctx, "PIN is blocked\n"); + sc_debug(card->ctx, "PIN is blocked\n"); return SC_ERROR_PIN_CODE_INCORRECT; case 0x6581: - sc_error(card->ctx, "out of space on card or file\n"); + sc_debug(card->ctx, "out of space on card or file\n"); return SC_ERROR_OUT_OF_MEMORY; case 0x6981: return SC_ERROR_FILE_NOT_FOUND; @@ -577,9 +577,7 @@ gpk_select_id(sc_card_t *card, int kind, unsigned int fid, fbuf[0] = fid >> 8; fbuf[1] = fid & 0xff; - sc_ctx_suppress_errors_on(card->ctx); r = gpk_select(card, kind, fbuf, 2, file); - sc_ctx_suppress_errors_off(card->ctx); /* Fix up the path cache. * NB we never cache the ID of an EF, just the DF path */ @@ -724,7 +722,7 @@ gpk_read_binary(sc_card_t *card, unsigned int offset, struct gpk_private_data *priv = DRVDATA(card); if (offset & priv->offset_mask) { - sc_error(card->ctx, "Invalid file offset (not a multiple of %d)", + sc_debug(card->ctx, "Invalid file offset (not a multiple of %d)", priv->offset_mask + 1); return SC_ERROR_INVALID_ARGUMENTS; } @@ -739,7 +737,7 @@ gpk_write_binary(sc_card_t *card, unsigned int offset, struct gpk_private_data *priv = DRVDATA(card); if (offset & priv->offset_mask) { - sc_error(card->ctx, "Invalid file offset (not a multiple of %d)", + sc_debug(card->ctx, "Invalid file offset (not a multiple of %d)", priv->offset_mask + 1); return SC_ERROR_INVALID_ARGUMENTS; } @@ -754,7 +752,7 @@ gpk_update_binary(sc_card_t *card, unsigned int offset, struct gpk_private_data *priv = DRVDATA(card); if (offset & priv->offset_mask) { - sc_error(card->ctx, "Invalid file offset (not a multiple of %d)", + sc_debug(card->ctx, "Invalid file offset (not a multiple of %d)", priv->offset_mask + 1); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1046,7 +1044,7 @@ gpk_set_security_env(sc_card_t *card, if (env->flags & SC_SEC_ENV_ALG_PRESENT) algorithm = env->algorithm; if (algorithm != SC_ALGORITHM_RSA) { - sc_error(card->ctx, "Algorithm not supported.\n"); + sc_debug(card->ctx, "Algorithm not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } priv->sec_algorithm = algorithm; @@ -1054,7 +1052,7 @@ gpk_set_security_env(sc_card_t *card, /* If there's a key reference, it must be 0 */ if ((env->flags & SC_SEC_ENV_KEY_REF_PRESENT) && (env->key_ref_len != 1 || env->key_ref[0] != 0)) { - sc_error(card->ctx, "Unknown key referenced.\n"); + sc_debug(card->ctx, "Unknown key referenced.\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -1067,7 +1065,7 @@ gpk_set_security_env(sc_card_t *card, else if (env->flags & SC_ALGORITHM_RSA_PAD_ISO9796) priv->sec_padding = 2; else { - sc_error(card->ctx, "Padding algorithm not supported.\n"); + sc_debug(card->ctx, "Padding algorithm not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -1090,7 +1088,7 @@ gpk_set_security_env(sc_card_t *card, context = GPK_SIGN_RSA_MD5; priv->sec_hash_len = 16; } else { - sc_error(card->ctx, "Unsupported signature algorithm"); + sc_debug(card->ctx, "Unsupported signature algorithm"); return SC_ERROR_NOT_SUPPORTED; } break; @@ -1098,20 +1096,20 @@ gpk_set_security_env(sc_card_t *card, context = GPK_UNWRAP_RSA; break; default: - sc_error(card->ctx, "Crypto operation not supported.\n"); + sc_debug(card->ctx, "Crypto operation not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } /* Get the file ID */ if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) { if (env->file_ref.len != 2) { - sc_error(card->ctx, "File reference: invalid length.\n"); + sc_debug(card->ctx, "File reference: invalid length.\n"); return SC_ERROR_INVALID_ARGUMENTS; } file_id = (env->file_ref.value[0] << 8) | env->file_ref.value[1]; } else { - sc_error(card->ctx, "File reference missing.\n"); + sc_debug(card->ctx, "File reference missing.\n"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1125,11 +1123,11 @@ gpk_set_security_env(sc_card_t *card, SC_RECORD_BY_REC_NR); SC_TEST_RET(card->ctx, r, "Failed to read PK sysrec"); if (r != 7 || sysrec[0] != 0) { - sc_error(card->ctx, "First record of file is not the sysrec"); + sc_debug(card->ctx, "First record of file is not the sysrec"); return SC_ERROR_OBJECT_NOT_VALID; } if (sysrec[5] != 0x00) { - sc_error(card->ctx, "Public key is not an RSA key"); + sc_debug(card->ctx, "Public key is not an RSA key"); return SC_ERROR_OBJECT_NOT_VALID; } switch (sysrec[1]) { @@ -1137,7 +1135,7 @@ gpk_set_security_env(sc_card_t *card, case 0x10: priv->sec_mod_len = 768 / 8; break; case 0x11: priv->sec_mod_len = 1024 / 8; break; default: - sc_error(card->ctx, "Unsupported modulus length"); + sc_debug(card->ctx, "Unsupported modulus length"); return SC_ERROR_OBJECT_NOT_VALID; } @@ -1269,7 +1267,7 @@ gpk_compute_signature(sc_card_t *card, const u8 *data, int r; if (data_len > priv->sec_mod_len) { - sc_error(card->ctx, + sc_debug(card->ctx, "Data length (%u) does not match key modulus %u.\n", data_len, priv->sec_mod_len); return SC_ERROR_INTERNAL; @@ -1330,7 +1328,7 @@ gpk_decipher(sc_card_t *card, const u8 *in, size_t inlen, int r; if (inlen != priv->sec_mod_len) { - sc_error(card->ctx, + sc_debug(card->ctx, "Data length (%u) does not match key modulus %u.\n", inlen, priv->sec_mod_len); return SC_ERROR_INVALID_ARGUMENTS; @@ -1517,7 +1515,7 @@ gpk_generate_key(sc_card_t *card, struct sc_cardctl_gpk_genkey *args) if (card->ctx->debug) sc_debug(card->ctx, "gpk_generate_key(%u)\n", args->privlen); if (args->privlen != 512 && args->privlen != 1024) { - sc_error(card->ctx, + sc_debug(card->ctx, "Key generation not supported for key length %d", args->privlen); return SC_ERROR_NOT_SUPPORTED; @@ -1589,7 +1587,7 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) /* encrypt the private key material */ assert(args->datalen <= sizeof(temp)); if (!priv->key_set) { - sc_error(card->ctx, "No secure messaging key set!\n"); + sc_debug(card->ctx, "No secure messaging key set!\n"); return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; } @@ -1694,7 +1692,7 @@ static int gpk_get_info(sc_card_t *card, int p1, int p2, u8 *buf, apdu.resplen = buflen; if ((r = sc_transmit_apdu(card, &apdu)) < 0) { - sc_error(card->ctx, "APDU transmit failed: %s", + sc_debug(card->ctx, "APDU transmit failed: %s", sc_strerror(r)); sc_unlock(card); return r; diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index df8414c7..65812bd6 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -154,13 +154,13 @@ static int incrypto34_check_sw(sc_card_t *card, unsigned int sw1, unsigned int s for (i = 0; i < err_count; i++) { if (incrypto34_errors[i].SWs == ((sw1 << 8) | sw2)) { if ( incrypto34_errors[i].errorstr ) - sc_error(card->ctx, "%s\n", + sc_debug(card->ctx, "%s\n", incrypto34_errors[i].errorstr); return incrypto34_errors[i].errorno; } } - sc_error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); + sc_debug(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); return SC_ERROR_CARD_CMD_FAILED; } @@ -392,7 +392,7 @@ static int incrypto34_create_file(sc_card_t *card, sc_file_t *file) byte = acl_to_byte( sc_file_get_acl_entry(file, idx[i])); if (byte < 0) { - sc_error(card->ctx, "Invalid ACL\n"); + sc_debug(card->ctx, "Invalid ACL\n"); r = SC_ERROR_INVALID_ARGUMENTS; goto out; } @@ -452,7 +452,7 @@ static int incrypto34_set_security_env(sc_card_t *card, if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) || env->key_ref_len != 1) { - sc_error(card->ctx, "No or invalid key reference\n"); + sc_debug(card->ctx, "No or invalid key reference\n"); return SC_ERROR_INVALID_ARGUMENTS; } key_id = env->key_ref[0]; @@ -553,9 +553,7 @@ incrypto34_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, */ if (ctx->debug >= 3) sc_debug(ctx, "trying RSA_PURE_SIG (padded DigestInfo)\n"); - sc_ctx_suppress_errors_on(ctx); r = do_compute_signature(card, data, datalen, out, outlen); - sc_ctx_suppress_errors_off(ctx); if (r >= SC_SUCCESS) SC_FUNC_RETURN(ctx, 4, r); if (ctx->debug >= 3) @@ -574,9 +572,7 @@ incrypto34_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, } memcpy(buf, p, tmp_len); } - sc_ctx_suppress_errors_on(ctx); r = do_compute_signature(card, buf, tmp_len, out, outlen); - sc_ctx_suppress_errors_off(ctx); if (r >= SC_SUCCESS) SC_FUNC_RETURN(ctx, 4, r); if (ctx->debug >= 3) @@ -624,7 +620,7 @@ incrypto34_lifecycle_get(sc_card_t *card, int *mode) *mode = SC_CARDCTRL_LIFECYCLE_OTHER; break; default: - sc_error(card->ctx, "Unknown lifecycle byte %d", rbuf[0]); + sc_debug(card->ctx, "Unknown lifecycle byte %d", rbuf[0]); r = SC_ERROR_INTERNAL; } diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index 90380ebd..8aa47559 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -328,9 +328,7 @@ static int jcop_read_binary(sc_card_t *card, unsigned int idx, if (idx + count > 128) { count=128-idx; } - sc_ctx_suppress_errors_on(card->ctx); r = iso_ops->select_file(card, &drvdata->aid, &tfile); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) { /* no pkcs15 app, so return empty DIR. */ memset(buf, 0, count); } else { @@ -356,9 +354,7 @@ static int jcop_list_files(sc_card_t *card, u8 *buf, size_t buflen) { if (buflen < 4) return 2; /* AppDF only exists if applet is selectable */ - sc_ctx_suppress_errors_on(card->ctx); r = iso_ops->select_file(card, &drvdata->aid, &tfile); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) { return 2; } else { @@ -650,11 +646,11 @@ static int jcop_set_security_env(sc_card_t *card, tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; if (tmp.algorithm != SC_ALGORITHM_RSA) { - sc_error(card->ctx, "Only RSA algorithm supported.\n"); + sc_debug(card->ctx, "Only RSA algorithm supported.\n"); return SC_ERROR_NOT_SUPPORTED; } if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)){ - sc_error(card->ctx, "Card requires RSA padding\n"); + sc_debug(card->ctx, "Card requires RSA padding\n"); return SC_ERROR_NOT_SUPPORTED; } tmp.algorithm_ref = 0x02; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index f2489ff0..95b59250 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -758,9 +758,7 @@ select_part(sc_card_t * card, u8 kind, unsigned short int fid, fbuf[0] = fid >> 8; fbuf[1] = fid & 0xff; - sc_ctx_suppress_errors_on(card->ctx); r = do_select(card, kind, fbuf, 2, file); - sc_ctx_suppress_errors_off(card->ctx); return r; } diff --git a/src/libopensc/card-miocos.c b/src/libopensc/card-miocos.c index 567815d4..cb4050be 100644 --- a/src/libopensc/card-miocos.c +++ b/src/libopensc/card-miocos.c @@ -141,7 +141,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, *p++ = 0x43; break; default: - sc_error(card->ctx, "Invalid EF structure\n"); + sc_debug(card->ctx, "Invalid EF structure\n"); return SC_ERROR_INVALID_ARGUMENTS; } ops = ef_ops; @@ -151,7 +151,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, ops = key_ops; break; default: - sc_error(card->ctx, "Unknown file type\n"); + sc_debug(card->ctx, "Unknown file type\n"); return SC_ERROR_INVALID_ARGUMENTS; } if (file->type == SC_FILE_TYPE_DF) { @@ -172,7 +172,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, else { int byte = acl_to_byte(sc_file_get_acl_entry(file, ops[i])); if (byte < 0) { - sc_error(card->ctx, "Invalid ACL\n"); + sc_debug(card->ctx, "Invalid ACL\n"); return SC_ERROR_INVALID_ARGUMENTS; } nibble = byte; @@ -239,7 +239,7 @@ static int miocos_set_security_env(sc_card_t *card, tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; if (tmp.algorithm != SC_ALGORITHM_RSA) { - sc_error(card->ctx, "Only RSA algorithm supported.\n"); + sc_debug(card->ctx, "Only RSA algorithm supported.\n"); return SC_ERROR_NOT_SUPPORTED; } tmp.algorithm_ref = 0x00; @@ -418,7 +418,7 @@ static int miocos_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, 1); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { - sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } r = sc_select_file(card, path, NULL); @@ -456,7 +456,7 @@ static int miocos_create_ac(sc_card_t *card, sendsize = 20; break; default: - sc_error(card->ctx, "AC type %d not supported\n", ac->type); + sc_debug(card->ctx, "AC type %d not supported\n", ac->type); return SC_ERROR_NOT_SUPPORTED; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x1E, miocos_type, @@ -476,7 +476,7 @@ static int miocos_card_ctl(sc_card_t *card, unsigned long cmd, case SC_CARDCTL_MIOCOS_CREATE_AC: return miocos_create_ac(card, (struct sc_cardctl_miocos_ac_info *) arg); } - sc_error(card->ctx, "card_ctl command 0x%X not supported\n", cmd); + sc_debug(card->ctx, "card_ctl command 0x%X not supported\n", cmd); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/libopensc/card-muscle.c b/src/libopensc/card-muscle.c index c7dc1231..e3d1a160 100644 --- a/src/libopensc/card-muscle.c +++ b/src/libopensc/card-muscle.c @@ -75,9 +75,7 @@ static int muscle_match_card(sc_card_t *card) * however it's not always properly nulled out... */ card->ops->logout = NULL; - sc_ctx_suppress_errors_on(card->ctx); i = msc_select_applet(card, muscleAppletId, 5); - sc_ctx_suppress_errors_off(card->ctx); /* Mark the card for muscle_init */ card->drv_data = (void*)0xFFFFFFFF; return i; @@ -282,14 +280,12 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data) } if((0 == memcmp(oid, "\x3F\x00\x00\x00", 4)) || (0 == memcmp(oid, "\x3F\x00\x3F\x00", 4))) { - sc_ctx_suppress_errors_on(card->ctx); } r = msc_delete_object(card, id, 1); /* Check if its the root... this file generally is virtual * So don't return an error if it fails */ if((0 == memcmp(oid, "\x3F\x00\x00\x00", 4)) || (0 == memcmp(oid, "\x3F\x00\x3F\x00", 4))) - sc_ctx_suppress_errors_off(card->ctx); return 0; if(r < 0) { @@ -560,7 +556,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, case SC_AC_AUT: case SC_AC_NONE: default: - sc_error(card->ctx, "Unsupported authentication method\n"); + sc_debug(card->ctx, "Unsupported authentication method\n"); return SC_ERROR_NOT_SUPPORTED; } case SC_PIN_CMD_CHANGE: @@ -576,7 +572,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, case SC_AC_AUT: case SC_AC_NONE: default: - sc_error(card->ctx, "Unsupported authentication method\n"); + sc_debug(card->ctx, "Unsupported authentication method\n"); return SC_ERROR_NOT_SUPPORTED; } case SC_PIN_CMD_UNBLOCK: @@ -592,11 +588,11 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd, case SC_AC_AUT: case SC_AC_NONE: default: - sc_error(card->ctx, "Unsupported authentication method\n"); + sc_debug(card->ctx, "Unsupported authentication method\n"); return SC_ERROR_NOT_SUPPORTED; } default: - sc_error(card->ctx, "Unsupported command\n"); + sc_debug(card->ctx, "Unsupported command\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -673,34 +669,34 @@ static int muscle_set_security_env(sc_card_t *card, if (env->operation != SC_SEC_OPERATION_SIGN && env->operation != SC_SEC_OPERATION_DECIPHER) { - sc_error(card->ctx, "Invalid crypto operation supplied.\n"); + sc_debug(card->ctx, "Invalid crypto operation supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->algorithm != SC_ALGORITHM_RSA) { - sc_error(card->ctx, "Invalid crypto algorithm supplied.\n"); + sc_debug(card->ctx, "Invalid crypto algorithm supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } /* ADJUST FOR PKCS1 padding support for decryption only */ if ((env->algorithm_flags & SC_ALGORITHM_RSA_PADS) || (env->algorithm_flags & SC_ALGORITHM_RSA_HASHES)) { - sc_error(card->ctx, "Card supports only raw RSA.\n"); + sc_debug(card->ctx, "Card supports only raw RSA.\n"); return SC_ERROR_NOT_SUPPORTED; } if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) { if (env->key_ref_len != 1 || (env->key_ref[0] > 0x0F)) { - sc_error(card->ctx, "Invalid key reference supplied.\n"); + sc_debug(card->ctx, "Invalid key reference supplied.\n"); return SC_ERROR_NOT_SUPPORTED; } priv->rsa_key_ref = env->key_ref[0]; } if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) { - sc_error(card->ctx, "Algorithm reference not supported.\n"); + sc_debug(card->ctx, "Algorithm reference not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } /* if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) if (memcmp(env->file_ref.value, "\x00\x12", 2) != 0) { - sc_error(card->ctx, "File reference is not 0012.\n"); + sc_debug(card->ctx, "File reference is not 0012.\n"); return SC_ERROR_NOT_SUPPORTED; } */ priv->env = *env; @@ -731,7 +727,7 @@ static int muscle_decipher(sc_card_t * card, key_id = priv->rsa_key_ref * 2; /* Private key */ if (out_len < crgram_len) { - sc_error(card->ctx, "Output buffer too small"); + sc_debug(card->ctx, "Output buffer too small"); return SC_ERROR_BUFFER_TOO_SMALL; } @@ -757,7 +753,7 @@ static int muscle_compute_signature(sc_card_t *card, const u8 *data, key_id = priv->rsa_key_ref * 2; /* Private key */ if (outlen < data_len) { - sc_error(card->ctx, "Output buffer too small"); + sc_debug(card->ctx, "Output buffer too small"); return SC_ERROR_BUFFER_TOO_SMALL; } diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index a76c2a34..03283f39 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -262,7 +262,7 @@ auth_init(sc_card_t *card) card->caps |= SC_CARD_CAP_USE_FCI_AC; if (auth_select_aid(card)) { - sc_error(card->ctx, "Failed to initialize %s\n", card->name); + sc_debug(card->ctx, "Failed to initialize %s\n", card->name); SC_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Failed to initialize"); } @@ -414,7 +414,7 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, else if (file->size==2048) file->size = PUBKEY_2048_ASN1_SIZE; else { - sc_error(card->ctx, "Not supported public key size: %i\n", file->size); + sc_debug(card->ctx, "Not supported public key size: %i\n", file->size); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_UNKNOWN_DATA_RECEIVED); } break; @@ -671,7 +671,7 @@ auth_delete_file(sc_card_t *card, const sc_path_t *path) } if (path->len < 2) { - sc_error(card->ctx, "Invalid path length\n"); + sc_debug(card->ctx, "Invalid path length\n"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } @@ -832,7 +832,7 @@ encode_file_structure_V5(sc_card_t *card, const sc_file_t *file, rv = SC_ERROR_INVALID_ARGUMENTS; if (rv) { - sc_error(card->ctx, "Invalid EF structure %i/%i\n", + sc_debug(card->ctx, "Invalid EF structure %i/%i\n", file->type, file->ef_structure); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INCORRECT_PARAMETERS); } @@ -860,7 +860,7 @@ encode_file_structure_V5(sc_card_t *card, const sc_file_t *file, else if (file->size == PUBKEY_2048_ASN1_SIZE || file->size == 2048) size = 2048; else { - sc_error(card->ctx, "incorrect RSA size %X\n", file->size); + sc_debug(card->ctx, "incorrect RSA size %X\n", file->size); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INCORRECT_PARAMETERS); } } @@ -873,7 +873,7 @@ encode_file_structure_V5(sc_card_t *card, const sc_file_t *file, else if (file->size == 24 || file->size == 192) size = 192; else { - sc_error(card->ctx, "incorrect DES size %X\n", file->size); + sc_debug(card->ctx, "incorrect DES size %X\n", file->size); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INCORRECT_PARAMETERS); } } @@ -992,7 +992,7 @@ auth_create_file(sc_card_t *card, sc_file_t *file) path.len -= 2; if (auth_select_file(card, &path, NULL)) { - sc_error(card->ctx, "Cannot select parent DF.\n"); + sc_debug(card->ctx, "Cannot select parent DF.\n"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } } @@ -1077,7 +1077,7 @@ auth_set_security_env(sc_card_t *card, apdu.datalen = 3; } else { - sc_error(card->ctx, "Invalid crypto operation: %X\n", env->operation); + sc_debug(card->ctx, "Invalid crypto operation: %X\n", env->operation); SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Invalid crypto operation"); } @@ -1089,7 +1089,7 @@ auth_set_security_env(sc_card_t *card, } if (pads & (~supported_pads)) { - sc_error(card->ctx, "No support for PAD %X\n",pads); + sc_debug(card->ctx, "No support for PAD %X\n",pads); SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "No padding support."); } @@ -1110,7 +1110,7 @@ auth_set_security_env(sc_card_t *card, apdu.data = rsa_sbuf; } else { - sc_error(card->ctx, "Invalid crypto operation: %X\n", env->operation); + sc_debug(card->ctx, "Invalid crypto operation: %X\n", env->operation); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } @@ -1151,7 +1151,7 @@ auth_compute_signature(sc_card_t *card, SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } else if (ilen > 96) { - sc_error(card->ctx, "Illegal input length %d\n", ilen); + sc_debug(card->ctx, "Illegal input length %d\n", ilen); SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Illegal input length"); } @@ -1169,7 +1169,7 @@ auth_compute_signature(sc_card_t *card, SC_TEST_RET(card->ctx, rv, "Compute signature failed"); if (apdu.resplen > olen) { - sc_error(card->ctx, "Compute signature failed: invalide response length %i\n", + sc_debug(card->ctx, "Compute signature failed: invalide response length %i\n", apdu.resplen); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_CARD_CMD_FAILED); } @@ -1445,7 +1445,7 @@ auth_update_component(sc_card_t *card, struct auth_update_component_info *args) EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, args->data, NULL); rv = EVP_EncryptUpdate(&ctx, out, &outl, in, 8); if (!EVP_CIPHER_CTX_cleanup(&ctx) || rv == 0) { - sc_error(card->ctx, "OpenSSL encryption error."); + sc_debug(card->ctx, "OpenSSL encryption error."); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL); } @@ -2440,7 +2440,7 @@ auth_sm_read_binary (struct sc_card *card, unsigned char *id, size_t id_len, sc_debug(card->ctx, "called; offs %i; len %i\n", offs, len); if (len > 0xF0) { - sc_error(card->ctx, "Not yet: reading length cannot be more then 240 bytes."); + sc_debug(card->ctx, "Not yet: reading length cannot be more then 240 bytes."); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } diff --git a/src/libopensc/card-openpgp.c b/src/libopensc/card-openpgp.c index 04d47ccf..da300bf7 100644 --- a/src/libopensc/card-openpgp.c +++ b/src/libopensc/card-openpgp.c @@ -235,9 +235,7 @@ pgp_read_blob(sc_card_t *card, struct blob *blob) if (blob->info == NULL) return blob->status; - sc_ctx_suppress_errors_on(card->ctx); r = blob->info->get_fn(card, blob->id, buffer, sizeof(buffer)); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) { blob->status = r; @@ -308,7 +306,7 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob) return 0; -eoc: sc_error(card->ctx, "Unexpected end of contents\n"); +eoc: sc_debug(card->ctx, "Unexpected end of contents\n"); return SC_ERROR_OBJECT_NOT_VALID; } @@ -556,7 +554,7 @@ pgp_set_security_env(sc_card_t *card, case SC_SEC_OPERATION_SIGN: if (env->key_ref[0] != 0x00 && env->key_ref[0] != 0x02) { - sc_error(card->ctx, + sc_debug(card->ctx, "Key reference not compatible with " "requested usage\n"); return SC_ERROR_NOT_SUPPORTED; @@ -564,7 +562,7 @@ pgp_set_security_env(sc_card_t *card, break; case SC_SEC_OPERATION_DECIPHER: if (env->key_ref[0] != 0x01) { - sc_error(card->ctx, + sc_debug(card->ctx, "Key reference not compatible with " "requested usage\n"); return SC_ERROR_NOT_SUPPORTED; @@ -602,11 +600,11 @@ pgp_compute_signature(sc_card_t *card, const u8 *data, 0x88, 0, 0); break; case 0x01: - sc_error(card->ctx, + sc_debug(card->ctx, "Invalid key reference (decipher only key)\n"); return SC_ERROR_INVALID_ARGUMENTS; default: - sc_error(card->ctx, "Invalid key reference 0x%02x\n", + sc_debug(card->ctx, "Invalid key reference 0x%02x\n", env->key_ref[0]); return SC_ERROR_INVALID_ARGUMENTS; } @@ -658,12 +656,12 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen, break; case 0x00: /* signature key */ case 0x02: /* authentication key */ - sc_error(card->ctx, + sc_debug(card->ctx, "Invalid key reference (signature only key)\n"); free(temp); return SC_ERROR_INVALID_ARGUMENTS; default: - sc_error(card->ctx, "Invalid key reference 0x%02x\n", + sc_debug(card->ctx, "Invalid key reference 0x%02x\n", env->key_ref[0]); free(temp); return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 2707cb03..94565aef 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -853,7 +853,7 @@ static int piv_cache_internal_data(sc_card_t *card, int enumtag) priv->obj_cache[enumtag].internal_obj_data = newBuf; priv->obj_cache[enumtag].internal_obj_len = len; #else - sc_error(card->ctx,"PIV compression not supported, no zlib"); + sc_debug(card->ctx,"PIV compression not supported, no zlib"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); #endif } else { @@ -1698,9 +1698,7 @@ static int piv_select_file(sc_card_t *card, const sc_path_t *in_path, if (file_out) { /* we need to read it now, to get length into cache */ - sc_ctx_suppress_errors_on(card->ctx); r = piv_get_cached_data(card, i, &rbuf, &rbuflen); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_FILE_NOT_FOUND); @@ -1757,7 +1755,6 @@ sc_debug(card->ctx,"DEE freeing #%d, %p:%d %p:%d", i, free(priv); } /* TODO temp see piv_init */ - sc_ctx_suppress_errors_off(card->ctx); return 0; } @@ -1772,9 +1769,7 @@ static int piv_match_card(sc_card_t *card) card->ops->logout = NULL; /* Detect by selecting applet */ - sc_ctx_suppress_errors_on(card->ctx); i = !(piv_find_aid(card, &aidfile)); - sc_ctx_suppress_errors_off(card->ctx); return i; /* never match */ } @@ -1807,7 +1802,7 @@ static int piv_init(sc_card_t *card) r = piv_find_aid(card, priv->aid_file); if (r < 0) { - sc_error(card->ctx, "Failed to initialize %s\n", card->name); + sc_debug(card->ctx, "Failed to initialize %s\n", card->name); SC_FUNC_RETURN(card->ctx, 1, r); } priv->enumtag = piv_aids[r].enumtag; @@ -1823,7 +1818,6 @@ static int piv_init(sc_card_t *card) if (r > 0) r = 0; -sc_ctx_suppress_errors_on(card->ctx); /*TODO temp to suppresss all error */ SC_FUNC_RETURN(card->ctx, 1, r); } diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index ef166e68..79ada5af 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -418,7 +418,7 @@ static int rtecp_rsa_cipher(sc_card_t *card, const u8 *data, size_t data_len, assert(buf); free(buf); if (r) - sc_error(card->ctx, "APDU transmit failed: %s\n", sc_strerror(r)); + sc_debug(card->ctx, "APDU transmit failed: %s\n", sc_strerror(r)); else { if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) @@ -653,7 +653,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) if (card->ctx->debug >= 4) sc_debug(card->ctx, "%s\n", "SC_CARDCTL_LIFECYCLE_SET not supported"); - /* no call sc_error (SC_FUNC_RETURN) */ + /* no call sc_debug (SC_FUNC_RETURN) */ return SC_ERROR_NOT_SUPPORTED; default: if (card->ctx->debug >= 3) diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index c58c18de..5d1fcc8c 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -237,12 +237,12 @@ static int rutoken_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) for (i = 0; i < sizeof(rutoken_errors)/sizeof(rutoken_errors[0]); ++i) { if (rutoken_errors[i].SWs == ((sw1 << 8) | sw2)) { if ( rutoken_errors[i].errorstr ) - sc_error(card->ctx, "%s\n", rutoken_errors[i].errorstr); + sc_debug(card->ctx, "%s\n", rutoken_errors[i].errorstr); sc_debug(card->ctx, "sw1 = %x, sw2 = %x", sw1, sw2); return rutoken_errors[i].errorno; } } - sc_error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); + sc_debug(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); return SC_ERROR_CARD_CMD_FAILED; } @@ -606,7 +606,7 @@ static int rutoken_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, 1); if (!path || path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2)) { - sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } if (path->len == sizeof(sbuf)) @@ -725,7 +725,7 @@ static int rutoken_reset_retry_counter(sc_card_t *card, unsigned int type, if (puk && puklen) { ret = rutoken_verify(card, type, ref_qualifier, puk, puklen, &left); - sc_error(card->ctx, "Tries left: %i\n", left); + sc_debug(card->ctx, "Tries left: %i\n", left); SC_TEST_RET(card->ctx, ret, "Invalid 'puk' pass"); } #endif @@ -773,7 +773,7 @@ static int rutoken_set_security_env(sc_card_t *card, senv->algorithm = SC_ALGORITHM_GOST; if (env->key_ref_len != 1) { - sc_error(card->ctx, "No or invalid key reference\n"); + sc_debug(card->ctx, "No or invalid key reference\n"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } data[2] = env->key_ref[0]; @@ -1311,7 +1311,7 @@ static int cipher_ext(sc_card_t *card, const u8 *data, size_t len, ret = SC_ERROR_INTERNAL; ERR_load_crypto_strings(); ERR_error_string(ERR_get_error(), error); - sc_error(card->ctx, error); + sc_debug(card->ctx, error); ERR_free_strings(); } } @@ -1507,7 +1507,7 @@ static int rutoken_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) case SC_CARDCTL_LIFECYCLE_SET: sc_debug(card->ctx, "SC_CARDCTL_LIFECYCLE_SET not supported"); sc_debug(card->ctx, "returning SC_ERROR_NOT_SUPPORTED"); - /* no call sc_error (SC_FUNC_RETURN) */ + /* no call sc_debug (SC_FUNC_RETURN) */ return SC_ERROR_NOT_SUPPORTED; } } diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index 5160c23c..b0ad094e 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -145,9 +145,7 @@ static int select_pkcs15_app(sc_card_t * card) /* Regular PKCS#15 AID */ sc_format_path("A000000063504B43532D3135", &app); app.type = SC_PATH_TYPE_DF_NAME; - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &app, NULL); - sc_ctx_suppress_errors_off(card->ctx); return r; } @@ -474,7 +472,7 @@ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file) break; case SC_AC_CHV: /* pin */ if ((bNumber & 0x7F) == 0 || (bNumber & 0x7F) > 7) { - sc_error(card->ctx, "SetCOS 4.4 PIN refs can only be 1..7\n"); + sc_debug(card->ctx, "SetCOS 4.4 PIN refs can only be 1..7\n"); return SC_ERROR_INVALID_ARGUMENTS; } bCommands_pin[setcos_pin_index_44(pins, sizeof(pins), (int) bNumber)] |= 1 << i; @@ -577,11 +575,11 @@ static int setcos_set_security_env2(sc_card_t *card, card->type == SC_CARD_TYPE_SETCOS_NIDEL || SETCOS_IS_EID_APPLET(card)) { if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) { - sc_error(card->ctx, "asymmetric keyref not supported.\n"); + sc_debug(card->ctx, "asymmetric keyref not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } if (se_num > 0) { - sc_error(card->ctx, "restore security environment not supported.\n"); + sc_debug(card->ctx, "restore security environment not supported.\n"); return SC_ERROR_NOT_SUPPORTED; } } @@ -671,7 +669,7 @@ static int setcos_set_security_env(sc_card_t *card, tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; if (tmp.algorithm != SC_ALGORITHM_RSA) { - sc_error(card->ctx, "Only RSA algorithm supported.\n"); + sc_debug(card->ctx, "Only RSA algorithm supported.\n"); return SC_ERROR_NOT_SUPPORTED; } switch (card->type) { @@ -684,7 +682,7 @@ static int setcos_set_security_env(sc_card_t *card, case SC_CARD_TYPE_SETCOS_EID_V2_1: break; default: - sc_error(card->ctx, "Card does not support RSA.\n"); + sc_debug(card->ctx, "Card does not support RSA.\n"); return SC_ERROR_NOT_SUPPORTED; break; } diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index d87d6996..ea943d7c 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1101,11 +1101,9 @@ static int starcos_set_security_env(sc_card_t *card, apdu.datalen = p - sbuf; apdu.lc = p - sbuf; apdu.le = 0; - /* suppress errors, as don't know whether to use + /* we don't know whether to use * COMPUTE SIGNATURE or INTERNAL AUTHENTICATE */ - sc_ctx_suppress_errors_on(card->ctx); r = sc_transmit_apdu(card, &apdu); - sc_ctx_suppress_errors_off(card->ctx); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { ex_data->fix_digestInfo = 0; @@ -1246,7 +1244,7 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) return SC_NO_ERROR; if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 ) { - sc_error(card->ctx, "Verification failed (remaining tries: %d)\n", + sc_debug(card->ctx, "Verification failed (remaining tries: %d)\n", (sw2 & 0x0f)); return SC_ERROR_PIN_CODE_INCORRECT; } @@ -1255,7 +1253,7 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) for (i = 0; i < err_count; i++) if (starcos_errors[i].SWs == ((sw1 << 8) | sw2)) { - sc_error(card->ctx, "%s\n", starcos_errors[i].errorstr); + sc_debug(card->ctx, "%s\n", starcos_errors[i].errorstr); return starcos_errors[i].errorno; } @@ -1340,9 +1338,7 @@ static int starcos_logout(sc_card_t *card) apdu.datalen = 2; apdu.resplen = 0; - sc_ctx_suppress_errors_on(card->ctx); r = sc_transmit_apdu(card, &apdu); - sc_ctx_suppress_errors_off(card->ctx); SC_TEST_RET(card->ctx, r, "APDU re-transmit failed"); if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85) diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index a03f5909..fc0e50fb 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -483,7 +483,7 @@ static int tcos_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, 1); if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) { - sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } sbuf[0] = path->value[0]; @@ -574,7 +574,7 @@ static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datal if(((tcos_data *)card->drv_data)->next_sign){ if(datalen>48){ - sc_error(card->ctx, "Data to be signed is too long (TCOS supports max. 48 bytes)\n"); + sc_debug(card->ctx, "Data to be signed is too long (TCOS supports max. 48 bytes)\n"); SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS); } sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 77091dc1..68abf48d 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -209,14 +209,10 @@ static int westcos_match_card(sc_card_t * card) apdu.lc = sizeof(aid); apdu.datalen = sizeof(aid); apdu.data = aid; - sc_ctx_suppress_errors_on(card->ctx); r = sc_transmit_apdu(card, &apdu); - sc_ctx_suppress_errors_off(card->ctx); if (r) continue; - sc_ctx_suppress_errors_on(card->ctx); r = sc_check_sw(card, apdu.sw1, apdu.sw2); - sc_ctx_suppress_errors_off(card->ctx); if (r) continue; } diff --git a/src/libopensc/card.c b/src/libopensc/card.c index 319a07c7..b672bc10 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -90,7 +90,7 @@ static void sc_card_free(sc_card_t *card) if (card->mutex != NULL) { int r = sc_mutex_destroy(card->ctx, card->mutex); if (r != SC_SUCCESS) - sc_error(card->ctx, "unable to destroy mutex\n"); + sc_debug(card->ctx, "unable to destroy mutex\n"); } sc_mem_clear(card, sizeof(*card)); free(card); @@ -172,7 +172,7 @@ int sc_connect_card(sc_reader_t *reader, int slot_id, sc_card_t **card_out) if (card->ops->init != NULL) { r = card->ops->init(card); if (r) { - sc_error(ctx, "driver '%s' init() failed: %s\n", card->driver->name, + sc_debug(ctx, "driver '%s' init() failed: %s\n", card->driver->name, sc_strerror(r)); goto err; } @@ -198,7 +198,7 @@ int sc_connect_card(sc_reader_t *reader, int slot_id, sc_card_t **card_out) card->driver = drv; r = ops->init(card); if (r) { - sc_error(ctx, "driver '%s' init() failed: %s\n", drv->name, + sc_debug(ctx, "driver '%s' init() failed: %s\n", drv->name, sc_strerror(r)); if (r == SC_ERROR_INVALID_CARD) { card->driver = NULL; @@ -210,7 +210,7 @@ int sc_connect_card(sc_reader_t *reader, int slot_id, sc_card_t **card_out) } } if (card->driver == NULL) { - sc_error(ctx, "unable to find driver for inserted card\n"); + sc_debug(ctx, "unable to find driver for inserted card\n"); r = SC_ERROR_INVALID_CARD; goto err; } @@ -238,13 +238,13 @@ int sc_disconnect_card(sc_card_t *card, int action) if (card->ops->finish) { int r = card->ops->finish(card); if (r) - sc_error(card->ctx, "card driver finish() failed: %s\n", + sc_debug(card->ctx, "card driver finish() failed: %s\n", sc_strerror(r)); } if (card->reader->ops->disconnect) { int r = card->reader->ops->disconnect(card->reader, card->slot); if (r) - sc_error(card->ctx, "disconnect() failed: %s\n", + sc_debug(card->ctx, "disconnect() failed: %s\n", sc_strerror(r)); } sc_card_free(card); @@ -271,7 +271,7 @@ int sc_reset(sc_card_t *card) r2 = sc_mutex_unlock(card->ctx, card->mutex); if (r2 != SC_SUCCESS) { - sc_error(card->ctx, "unable to release lock\n"); + sc_debug(card->ctx, "unable to release lock\n"); r = r != SC_SUCCESS ? r : r2; } @@ -299,7 +299,7 @@ int sc_lock(sc_card_t *card) card->lock_count++; r2 = sc_mutex_unlock(card->ctx, card->mutex); if (r2 != SC_SUCCESS) { - sc_error(card->ctx, "unable to release lock\n"); + sc_debug(card->ctx, "unable to release lock\n"); r = r != SC_SUCCESS ? r : r2; } return r; @@ -327,7 +327,7 @@ int sc_unlock(sc_card_t *card) } r2 = sc_mutex_unlock(card->ctx, card->mutex); if (r2 != SC_SUCCESS) { - sc_error(card->ctx, "unable to release lock\n"); + sc_debug(card->ctx, "unable to release lock\n"); r = (r == SC_SUCCESS) ? r2 : r; } return r; @@ -774,7 +774,7 @@ static int match_atr_table(sc_context_t *ctx, struct sc_atr_table *table, u8 *at mbin_len = sizeof(mbin); sc_hex_to_bin(matr, mbin, &mbin_len); if (mbin_len != fix_bin_len) { - sc_error(ctx,"length of atr and atr mask do not match - ignored: %s - %s", tatr, matr); + sc_debug(ctx,"length of atr and atr mask do not match - ignored: %s - %s", tatr, matr); continue; } for (s = 0; s < tbin_len; s++) { diff --git a/src/libopensc/ctbcs.c b/src/libopensc/ctbcs.c index 35c2ec3a..114e667a 100644 --- a/src/libopensc/ctbcs.c +++ b/src/libopensc/ctbcs.c @@ -169,7 +169,7 @@ ctbcs_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, r = ctbcs_build_modify_verification_apdu(&apdu, data, slot); break; default: - sc_error(reader->ctx, "Unknown PIN command %d", data->cmd); + sc_debug(reader->ctx, "Unknown PIN command %d", data->cmd); return SC_ERROR_NOT_SUPPORTED; } @@ -187,7 +187,7 @@ ctbcs_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, r = sc_transmit_apdu(card, &apdu); s = sc_mutex_destroy(reader->ctx, card->mutex); if (s != SC_SUCCESS) { - sc_error(reader->ctx, "unable to destroy mutex\n"); + sc_debug(reader->ctx, "unable to destroy mutex\n"); return s; } SC_TEST_RET(card->ctx, r, "APDU transmit failed"); diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index 9b2fb872..c64ce03b 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -176,13 +176,9 @@ static void add_internal_drvs(struct _sc_ctx_options *opts, int type) static void set_defaults(sc_context_t *ctx, struct _sc_ctx_options *opts) { ctx->debug = 0; - if (ctx->debug_file && ctx->debug_file != stdout) + if (ctx->debug_file && ctx->debug_file != stderr) fclose(ctx->debug_file); - ctx->debug_file = stdout; - ctx->suppress_errors = 0; - if (ctx->error_file && ctx->error_file != stderr) - fclose(ctx->error_file); - ctx->error_file = stderr; + ctx->debug_file = stderr; ctx->forced_driver = NULL; add_internal_drvs(opts, 0); add_internal_drvs(opts, 1); @@ -203,21 +199,14 @@ static int load_parameters(sc_context_t *ctx, scconf_block *block, val = scconf_get_str(block, "debug_file", NULL); if (val) { - if (ctx->debug_file && ctx->debug_file != stdout) + if (ctx->debug_file && (ctx->debug_file != stderr || ctx->debug_file != stdout)) fclose(ctx->debug_file); - if (strcmp(val, "stdout") != 0) - ctx->debug_file = fopen(val, "a"); + if (!strcmp(val, "stdout")) + ctx->debug_file = stdout; + else if (!strcmp(val, "stderr")) + ctx->debug_file = stderr; else - ctx->debug_file = stdout; - } - val = scconf_get_str(block, "error_file", NULL); - if (val) { - if (ctx->error_file && ctx->error_file != stderr) - fclose(ctx->error_file); - if (strcmp(val, "stderr") != 0) - ctx->error_file = fopen(val, "a"); - else - ctx->error_file = stderr; + ctx->debug_file = fopen(val, "a"); } val = scconf_get_str(block, "force_card_driver", NULL); if (val) { @@ -339,7 +328,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *(**tmodv)(void) = &modversion; if (name == NULL) { /* should not occurr, but... */ - sc_error(ctx,"No module specified\n",name); + sc_debug(ctx,"No module specified\n",name); return NULL; } libname = find_library(ctx, name, type); @@ -347,7 +336,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, return NULL; handle = lt_dlopen(libname); if (handle == NULL) { - sc_error(ctx, "Module %s: cannot load %s library: %s\n", name, libname, lt_dlerror()); + sc_debug(ctx, "Module %s: cannot load %s library: %s\n", name, libname, lt_dlerror()); return NULL; } @@ -355,7 +344,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, *(void **)tmodi = lt_dlsym(handle, "sc_module_init"); *(void **)tmodv = lt_dlsym(handle, "sc_driver_version"); if (modinit == NULL || modversion == NULL) { - sc_error(ctx, "dynamic library '%s' is not a OpenSC module\n",libname); + sc_debug(ctx, "dynamic library '%s' is not a OpenSC module\n",libname); lt_dlclose(handle); return NULL; } @@ -363,7 +352,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, version = modversion(); /* XXX: We really need to have ABI version for each interface */ if (version == NULL || strncmp(version, PACKAGE_VERSION, strlen(PACKAGE_VERSION)) != 0) { - sc_error(ctx,"dynamic library '%s': invalid module version\n",libname); + sc_debug(ctx,"dynamic library '%s': invalid module version\n",libname); lt_dlclose(handle); return NULL; } @@ -400,7 +389,7 @@ static int load_reader_drivers(sc_context_t *ctx, *(void**)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name, 0); /* if still null, assume driver not found */ if (func == NULL) { - sc_error(ctx, "Unable to load '%s'.\n", ent->name); + sc_debug(ctx, "Unable to load '%s'.\n", ent->name); continue; } driver = func(); @@ -463,7 +452,7 @@ static int load_card_drivers(sc_context_t *ctx, *(void **)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name, 1); /* if still null, assume driver not found */ if (func == NULL) { - sc_error(ctx, "Unable to load '%s'.\n", ent->name); + sc_debug(ctx, "Unable to load '%s'.\n", ent->name); continue; } @@ -624,7 +613,7 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts) if (r < 0) sc_debug(ctx, "scconf_parse failed: %s", ctx->conf->errmsg); else - sc_error(ctx, "scconf_parse failed: %s", ctx->conf->errmsg); + sc_debug(ctx, "scconf_parse failed: %s", ctx->conf->errmsg); scconf_free(ctx->conf); ctx->conf = NULL; return; @@ -676,16 +665,6 @@ unsigned int sc_ctx_get_reader_count(sc_context_t *ctx) return (unsigned int)ctx->reader_count; } -void sc_ctx_suppress_errors_on(sc_context_t *ctx) -{ - ctx->suppress_errors++; -} - -void sc_ctx_suppress_errors_off(sc_context_t *ctx) -{ - ctx->suppress_errors--; -} - int sc_establish_context(sc_context_t **ctx_out, const char *app_name) { sc_context_param_t ctx_param; @@ -791,16 +770,14 @@ int sc_release_context(sc_context_t *ctx) if (ctx->mutex != NULL) { int r = sc_mutex_destroy(ctx, ctx->mutex); if (r != SC_SUCCESS) { - sc_error(ctx, "unable to destroy mutex\n"); + sc_debug(ctx, "unable to destroy mutex\n"); return r; } } if (ctx->conf != NULL) scconf_free(ctx->conf); - if (ctx->debug_file && ctx->debug_file != stdout) + if (ctx->debug_file && (ctx->debug_file != stdout && ctx->debug_file != stderr)) fclose(ctx->debug_file); - if (ctx->error_file && ctx->error_file != stderr) - fclose(ctx->error_file); if (ctx->app_name != NULL) free(ctx->app_name); sc_mem_clear(ctx, sizeof(*ctx)); @@ -901,6 +878,6 @@ int sc_make_cache_dir(sc_context_t *ctx) return SC_SUCCESS; /* for lack of a better return code */ -failed: sc_error(ctx, "failed to create cache directory\n"); +failed: sc_debug(ctx, "failed to create cache directory\n"); return SC_ERROR_INTERNAL; } diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 189d54be..634e6e95 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -96,12 +96,12 @@ static int parse_dir_record(sc_card_t *card, u8 ** buf, size_t *buflen, if (r == SC_ERROR_ASN1_END_OF_CONTENTS) return r; if (r) { - sc_error(card->ctx, "EF(DIR) parsing failed: %s\n", + sc_debug(card->ctx, "EF(DIR) parsing failed: %s\n", sc_strerror(r)); return r; } if (aid_len > SC_MAX_AID_SIZE) { - sc_error(card->ctx, "AID is too long.\n"); + sc_debug(card->ctx, "AID is too long.\n"); return SC_ERROR_INVALID_ASN1_OBJECT; } app = (sc_app_info_t *) malloc(sizeof(sc_app_info_t)); @@ -116,7 +116,7 @@ static int parse_dir_record(sc_card_t *card, u8 ** buf, size_t *buflen, app->label = NULL; if (asn1_dirrecord[2].flags & SC_ASN1_PRESENT) { if (path_len > SC_MAX_PATH_SIZE) { - sc_error(card->ctx, "Application path is too long.\n"); + sc_debug(card->ctx, "Application path is too long.\n"); free(app); return SC_ERROR_INVALID_ASN1_OBJECT; } @@ -167,9 +167,7 @@ int sc_enum_apps(sc_card_t *card) sc_file_free(card->ef_dir); card->ef_dir = NULL; } - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, &card->ef_dir); - sc_ctx_suppress_errors_off(card->ctx); if (r) return r; if (card->ef_dir->type != SC_FILE_TYPE_WORKING_EF) { @@ -198,7 +196,7 @@ int sc_enum_apps(sc_card_t *card) bufsize = r; while (bufsize > 0) { if (card->app_count == SC_MAX_CARD_APPS) { - sc_error(card->ctx, "Too many applications on card"); + sc_debug(card->ctx, "Too many applications on card"); break; } r = parse_dir_record(card, &p, &bufsize, -1); @@ -214,15 +212,13 @@ int sc_enum_apps(sc_card_t *card) size_t rec_size; for (rec_nr = 1; ; rec_nr++) { - sc_ctx_suppress_errors_on(card->ctx); r = sc_read_record(card, rec_nr, buf, sizeof(buf), SC_RECORD_BY_REC_NR); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_ERROR_RECORD_NOT_FOUND) break; SC_TEST_RET(card->ctx, r, "read_record() failed"); if (card->app_count == SC_MAX_CARD_APPS) { - sc_error(card->ctx, "Too many applications on card"); + sc_debug(card->ctx, "Too many applications on card"); break; } rec_size = r; @@ -285,7 +281,7 @@ static int encode_dir_record(sc_context_t *ctx, const sc_app_info_t *app, (void *) &tapp.ddo_len, 1); r = sc_asn1_encode(ctx, asn1_dir, buf, buflen); if (r) { - sc_error(ctx, "sc_asn1_encode() failed: %s\n", + sc_debug(ctx, "sc_asn1_encode() failed: %s\n", sc_strerror(r)); return r; } @@ -352,9 +348,7 @@ static int update_single_record(sc_card_t *card, sc_file_t *file, r = sc_update_record(card, (unsigned int)app->rec_nr, rec, rec_size, SC_RECORD_BY_REC_NR); else if (app->rec_nr == 0) { /* create new record entry */ - sc_ctx_suppress_errors_on(card->ctx); r = sc_append_record(card, rec, rec_size, 0); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_ERROR_NOT_SUPPORTED) { /* if the card doesn't support APPEND RECORD we try a * UPDATE RECORD on the next unused record (and hope @@ -368,7 +362,7 @@ static int update_single_record(sc_card_t *card, sc_file_t *file, r = sc_update_record(card, (unsigned int)rec_nr, rec, rec_size, SC_RECORD_BY_REC_NR); } } else { - sc_error(card->ctx, "invalid record number\n"); + sc_debug(card->ctx, "invalid record number\n"); r = SC_ERROR_INTERNAL; } free(rec); diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 22e2613b..4c1e64ff 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -84,22 +84,22 @@ static int iso7816_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2) /* Handle special cases here */ if (sw1 == 0x6C) { - sc_error(card->ctx, "Wrong length; correct length is %d\n", sw2); + sc_debug(card->ctx, "Wrong length; correct length is %d\n", sw2); return SC_ERROR_WRONG_LENGTH; } if (sw1 == 0x90) return SC_NO_ERROR; if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) { - sc_error(card->ctx, "Verification failed (remaining tries: %d)\n", + sc_debug(card->ctx, "Verification failed (remaining tries: %d)\n", (sw2 & 0x0f)); return SC_ERROR_PIN_CODE_INCORRECT; } for (i = 0; i < err_count; i++) if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) { - sc_error(card->ctx, "%s\n", iso7816_errors[i].errorstr); + sc_debug(card->ctx, "%s\n", iso7816_errors[i].errorstr); return iso7816_errors[i].errorno; } - sc_error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); + sc_debug(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2); return SC_ERROR_CARD_CMD_FAILED; } @@ -112,7 +112,7 @@ static int iso7816_read_binary(sc_card_t *card, int r; if (idx > 0x7fff) { - sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx); + sc_debug(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx); return SC_ERROR_OFFSET_TOO_LARGE; } @@ -166,7 +166,7 @@ static int iso7816_write_record(sc_card_t *card, unsigned int rec_nr, int r; if (count > 256) { - sc_error(card->ctx, "Trying to send too many bytes\n"); + sc_debug(card->ctx, "Trying to send too many bytes\n"); return SC_ERROR_INVALID_ARGUMENTS; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD2, rec_nr, 0); @@ -193,7 +193,7 @@ static int iso7816_append_record(sc_card_t *card, int r; if (count > 256) { - sc_error(card->ctx, "Trying to send too many bytes\n"); + sc_debug(card->ctx, "Trying to send too many bytes\n"); return SC_ERROR_INVALID_ARGUMENTS; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE2, 0, 0); @@ -218,7 +218,7 @@ static int iso7816_update_record(sc_card_t *card, unsigned int rec_nr, int r; if (count > 256) { - sc_error(card->ctx, "Trying to send too many bytes\n"); + sc_debug(card->ctx, "Trying to send too many bytes\n"); return SC_ERROR_INVALID_ARGUMENTS; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDC, rec_nr, 0); @@ -247,7 +247,7 @@ static int iso7816_write_binary(sc_card_t *card, assert(count <= card->max_send_size); if (idx > 0x7fff) { - sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx); + sc_debug(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx); return SC_ERROR_OFFSET_TOO_LARGE; } @@ -274,7 +274,7 @@ static int iso7816_update_binary(sc_card_t *card, assert(count <= card->max_send_size); if (idx > 0x7fff) { - sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx); + sc_debug(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx); return SC_ERROR_OFFSET_TOO_LARGE; } @@ -642,7 +642,7 @@ static int iso7816_delete_file(sc_card_t *card, const sc_path_t *path) SC_FUNC_CALLED(card->ctx, 1); if (path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2)) { - sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); } @@ -946,7 +946,7 @@ static int iso7816_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, /* Call the reader driver to collect * the PIN and pass on the APDU to the card */ if (data->pin1.offset == 0) { - sc_error(card->ctx, + sc_debug(card->ctx, "Card driver didn't set PIN offset"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -958,7 +958,7 @@ static int iso7816_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, data); /* sw1/sw2 filled in by reader driver */ } else { - sc_error(card->ctx, + sc_debug(card->ctx, "Card reader driver does not support " "PIN entry through reader key pad"); r = SC_ERROR_NOT_SUPPORTED; diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 4589015f..f3d0e76e 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -1,7 +1,6 @@ _sc_asn1_decode _sc_asn1_encode _sc_debug -_sc_error sc_append_file_id sc_append_path sc_append_path_id @@ -41,8 +40,6 @@ sc_create_file sc_ctx_detect_readers sc_ctx_get_reader sc_ctx_get_reader_count -sc_ctx_suppress_errors_off -sc_ctx_suppress_errors_on sc_decipher sc_delete_file sc_delete_record diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 04afa34e..350616d4 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -35,16 +35,6 @@ #include #endif -/* Although not used, we need this for consistent exports */ -void _sc_error(sc_context_t *ctx, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - sc_do_log_va(ctx, SC_LOG_TYPE_ERROR, NULL, 0, NULL, format, ap); - va_end(ap); -} - /* Although not used, we need this for consistent exports */ void _sc_debug(sc_context_t *ctx, const char *format, ...) { @@ -75,17 +65,6 @@ void sc_do_log_va(sc_context_t *ctx, int type, const char *file, int line, const assert(ctx != NULL); switch (type) { - case SC_LOG_TYPE_ERROR: - if (!ctx->suppress_errors) { - display_fn = &sc_ui_display_error; - tag = "error:"; - break; - } - /* Fall thru - suppressed errors are logged as - * debug messages */ - tag = "error (suppressed):"; - type = SC_LOG_TYPE_DEBUG; - case SC_LOG_TYPE_DEBUG: if (ctx->debug == 0) return; diff --git a/src/libopensc/log.h b/src/libopensc/log.h index 15cd69a2..04dff00f 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -40,15 +40,12 @@ extern "C" { #if defined(__GNUC__) -#define sc_error(ctx, format, args...) sc_do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, format , ## args) #define sc_debug(ctx, format, args...) sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, format , ## args) #else -#define sc_error _sc_error #define sc_debug _sc_debug #endif -void _sc_error(struct sc_context *ctx, const char *format, ...); void _sc_debug(struct sc_context *ctx, const char *format, ...); void sc_do_log(struct sc_context *ctx, int type, const char *file, int line, const char *func, const char *format, ...); void sc_do_log_va(struct sc_context *ctx, int type, const char *file, int line, const char *func, const char *format, va_list args); @@ -62,11 +59,7 @@ void sc_hex_dump(struct sc_context *ctx, const u8 * buf, size_t len, char *out, #define SC_FUNC_RETURN(ctx, level, r) do { \ int _ret = r; \ - if (_ret < 0 && !ctx->suppress_errors) { \ - sc_do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, "returning with: %s\n", sc_strerror(_ret)); \ - } else if (ctx->debug >= level) { \ - sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "returning with: %d\n", _ret); \ - } \ + sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "returning with: %d\n", _ret); \ return _ret; \ } while(0) diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index fcee6de9..c9a8bc04 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -60,7 +60,7 @@ int msc_list_objects(sc_card_t* card, u8 next, mscfs_file_t* file) { if(apdu.resplen == 0) /* No more left */ return 0; if (apdu.resplen != 14) { - sc_error(card->ctx, "expected 14 bytes, got %d.\n", apdu.resplen); + sc_debug(card->ctx, "expected 14 bytes, got %d.\n", apdu.resplen); return SC_ERROR_UNKNOWN_DATA_RECEIVED; } memcpy(file->objectId.id, fileData, 4); @@ -498,9 +498,7 @@ int msc_get_challenge(sc_card_t *card, short dataLength, short seedLength, u8 *s r = msc_read_object(card, inputId, 2, outputData, dataLength); if(r < 0) SC_FUNC_RETURN(card->ctx, 0, r); - sc_ctx_suppress_errors_on(card->ctx); msc_delete_object(card, inputId,0); - sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 0, r); } } @@ -828,23 +826,19 @@ static int msc_compute_crypt_final_object( ptr++; memcpy(ptr, inputData, dataLength); - sc_ctx_suppress_errors_on(card->ctx); r = msc_create_object(card, outputId, dataLength + 2, 0x02, 0x02, 0x02); if(r < 0) { if(r == SC_ERROR_FILE_ALREADY_EXISTS) { r = msc_delete_object(card, outputId, 0); if(r < 0) { - sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 2, r); } r = msc_create_object(card, outputId, dataLength + 2, 0x02, 0x02, 0x02); if(r < 0) { - sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 2, r); } } } - sc_ctx_suppress_errors_off(card->ctx); r = msc_update_object(card, outputId, 0, buffer + 1, dataLength + 2); if(r < 0) return r; @@ -867,10 +861,8 @@ static int msc_compute_crypt_final_object( } else { r = SC_ERROR_CARD_CMD_FAILED; } - /* no error checks.. this is last ditch cleanup */ - sc_ctx_suppress_errors_on(card->ctx); + /* this is last ditch cleanup */ msc_delete_object(card, outputId, 0); - sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 0, r); } @@ -995,25 +987,21 @@ int msc_import_key(sc_card_t *card, CPYVAL(dq1); } - sc_ctx_suppress_errors_on(card->ctx); r = msc_create_object(card, outputId, bufferSize, 0x02, 0x02, 0x02); if(r < 0) { if(r == SC_ERROR_FILE_ALREADY_EXISTS) { r = msc_delete_object(card, outputId, 0); if(r < 0) { - sc_ctx_suppress_errors_off(card->ctx); free(buffer); SC_FUNC_RETURN(card->ctx, 2, r); } r = msc_create_object(card, outputId, bufferSize, 0x02, 0x02, 0x02); if(r < 0) { - sc_ctx_suppress_errors_off(card->ctx); free(buffer); SC_FUNC_RETURN(card->ctx, 2, r); } } } - sc_ctx_suppress_errors_off(card->ctx); r = msc_update_object(card, outputId, 0, buffer, bufferSize); free(buffer); @@ -1040,16 +1028,12 @@ int msc_import_key(sc_card_t *card, sc_debug(card->ctx, "keyimport: got strange SWs: 0x%02X 0x%02X\n", apdu.sw1, apdu.sw2); } - /* no error checks.. this is last ditch cleanup */ - sc_ctx_suppress_errors_on(card->ctx); + /* this is last ditch cleanup */ msc_delete_object(card, outputId, 0); - sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 0, r); } - /* no error checks.. this is last ditch cleanup */ - sc_ctx_suppress_errors_on(card->ctx); + /* this is last ditch cleanup */ msc_delete_object(card, outputId, 0); - sc_ctx_suppress_errors_off(card->ctx); SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_CARD_CMD_FAILED); } diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 1e79a293..6c105a84 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -650,8 +650,7 @@ typedef struct sc_context { char *app_name; int debug; - int suppress_errors; - FILE *debug_file, *error_file; + FILE *debug_file; char *preferred_language; const struct sc_reader_driver *reader_drivers[SC_MAX_READER_DRIVERS]; @@ -753,18 +752,6 @@ sc_reader_t *sc_ctx_get_reader(sc_context_t *ctx, unsigned int i); */ unsigned int sc_ctx_get_reader_count(sc_context_t *ctx); -/** - * Turns on error suppression - * @param ctx OpenSC context - */ -void sc_ctx_suppress_errors_on(sc_context_t *ctx); - -/** - * Turns off error suppression - * @param ctx OpenSC context - */ -void sc_ctx_suppress_errors_off(sc_context_t *ctx); - /** * Forces the use of a specified card driver * @param ctx OpenSC context diff --git a/src/libopensc/p15card-helper.c b/src/libopensc/p15card-helper.c index bdda10cb..31836479 100644 --- a/src/libopensc/p15card-helper.c +++ b/src/libopensc/p15card-helper.c @@ -142,29 +142,29 @@ CERT_HANDLE_FUNCTION(default_cert_handle) { int modulus_len = 0; const prdata* key = get_prkey_by_cert(items, cert); if(!key) { - sc_error(p15card->card->ctx, "Error: No key for this certificate"); + sc_debug(p15card->card->ctx, "Error: No key for this certificate"); return SC_ERROR_INTERNAL; } if(!d2i_X509(&cert_data, (const u8**)&data, length)) { - sc_error(p15card->card->ctx, "Error converting certificate"); + sc_debug(p15card->card->ctx, "Error converting certificate"); return SC_ERROR_INTERNAL; } pkey = X509_get_pubkey(cert_data); if(pkey == NULL) { - sc_error(p15card->card->ctx, "Error: no public key associated with the certificate"); + sc_debug(p15card->card->ctx, "Error: no public key associated with the certificate"); r = SC_ERROR_INTERNAL; goto err; } if(! EVP_PK_RSA & (certtype = X509_certificate_type(cert_data, pkey))) { - sc_error(p15card->card->ctx, "Error: certificate is not for an RSA key"); + sc_debug(p15card->card->ctx, "Error: certificate is not for an RSA key"); r = SC_ERROR_INTERNAL; goto err; } if(pkey->pkey.rsa->n == NULL) { - sc_error(p15card->card->ctx, "Error: no modulus associated with the certificate"); + sc_debug(p15card->card->ctx, "Error: no modulus associated with the certificate"); r = SC_ERROR_INTERNAL; goto err; } diff --git a/src/libopensc/p15emu-westcos.c b/src/libopensc/p15emu-westcos.c index 69e58908..77e0d1bb 100644 --- a/src/libopensc/p15emu-westcos.c +++ b/src/libopensc/p15emu-westcos.c @@ -63,9 +63,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) p15card->version = buf[6]; p15card->flags = SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED; sc_format_path("AAAA", &path); - sc_ctx_suppress_errors_on(ctx); r = sc_select_file(card, &path, &file); - sc_ctx_suppress_errors_off(ctx); if (!r) { for (i = 0; i < 1; i++) { unsigned int flags; @@ -110,9 +108,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) sc_file_free(file); file = NULL; sc_format_path("0002", &path); - sc_ctx_suppress_errors_on(ctx); r = sc_select_file(card, &path, &file); - sc_ctx_suppress_errors_off(ctx); if (!r) { struct sc_pkcs15_cert_info cert_info; struct sc_pkcs15_object cert_obj; @@ -125,11 +121,9 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) cert_info.id.value[0] = 0x45; cert_info.authority = 0; cert_info.path = path; - sc_ctx_suppress_errors_on(ctx); r = sc_pkcs15_read_certificate(p15card, &cert_info, (sc_pkcs15_cert_t **) (&cert_obj.data)); - sc_ctx_suppress_errors_off(ctx); if (!r) { sc_pkcs15_cert_t *cert = (sc_pkcs15_cert_t *) (cert_obj.data); @@ -189,9 +183,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) sc_file_free(file); file = NULL; sc_format_path("0001", &path); - sc_ctx_suppress_errors_on(ctx); r = sc_select_file(card, &path, &file); - sc_ctx_suppress_errors_off(ctx); if (!r) { struct sc_pkcs15_prkey_info prkey_info; struct sc_pkcs15_object prkey_obj; diff --git a/src/libopensc/padding.c b/src/libopensc/padding.c index f213841c..524ea649 100644 --- a/src/libopensc/padding.c +++ b/src/libopensc/padding.c @@ -231,7 +231,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, i = sc_pkcs1_add_digest_info_prefix(hash_algo, in, in_len, out, &tmp_len); if (i != SC_SUCCESS) { - sc_error(ctx, "Unable to add digest info 0x%x\n", + sc_debug(ctx, "Unable to add digest info 0x%x\n", hash_algo); return i; } @@ -252,7 +252,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags, mod_len); default: /* currently only pkcs1 padding is supported */ - sc_error(ctx, "Unsupported padding algorithm 0x%x\n", pad_algo); + sc_debug(ctx, "Unsupported padding algorithm 0x%x\n", pad_algo); return SC_ERROR_NOT_SUPPORTED; } } @@ -284,14 +284,14 @@ int sc_get_encoding_flags(sc_context_t *ctx, *pflags |= SC_ALGORITHM_RSA_PAD_PKCS1; } else if ((iflags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) { if (!(caps & SC_ALGORITHM_RSA_RAW)) { - sc_error(ctx, "raw RSA is not supported"); + sc_debug(ctx, "raw RSA is not supported"); return SC_ERROR_NOT_SUPPORTED; } *sflags |= SC_ALGORITHM_RSA_RAW; /* in case of raw RSA there is nothing to pad */ *pflags = 0; } else { - sc_error(ctx, "unsupported algorithm"); + sc_debug(ctx, "unsupported algorithm"); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index ea546e6c..9bc24a56 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -342,7 +342,7 @@ sc_asn1_encode_algorithm_id(sc_context_t *ctx, alg_info = sc_asn1_get_algorithm_info(id); if (alg_info == NULL) { - sc_error(ctx, "Cannot encode unknown algorithm %u.\n", + sc_debug(ctx, "Cannot encode unknown algorithm %u.\n", id->algorithm); return SC_ERROR_INVALID_ARGUMENTS; } diff --git a/src/libopensc/pkcs15-atrust-acos.c b/src/libopensc/pkcs15-atrust-acos.c index cc9726ff..071568da 100644 --- a/src/libopensc/pkcs15-atrust-acos.c +++ b/src/libopensc/pkcs15-atrust-acos.c @@ -95,9 +95,7 @@ static int acos_detect_card(sc_pkcs15_card_t *p15card) return SC_ERROR_WRONG_CARD; /* read EF_CIN_CSN file */ sc_format_path("DF71D001", &path); - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r != SC_SUCCESS) return SC_ERROR_WRONG_CARD; r = sc_read_binary(card, 0, buf, 8, 0); @@ -163,9 +161,7 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card) /* read EF_CIN_CSN file */ sc_format_path("DF71D001", &path); - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r != SC_SUCCESS) return SC_ERROR_INTERNAL; r = sc_read_binary(card, 0, buf, 8, 0); diff --git a/src/libopensc/pkcs15-cache.c b/src/libopensc/pkcs15-cache.c index 4cb526c9..217f4dc5 100644 --- a/src/libopensc/pkcs15-cache.c +++ b/src/libopensc/pkcs15-cache.c @@ -154,7 +154,7 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card, c = fwrite(buf, 1, bufsize, f); fclose(f); if (c != bufsize) { - sc_error(p15card->card->ctx, "fwrite() wrote only %d bytes", c); + sc_debug(p15card->card->ctx, "fwrite() wrote only %d bytes", c); unlink(fname); return SC_ERROR_INTERNAL; } diff --git a/src/libopensc/pkcs15-cert.c b/src/libopensc/pkcs15-cert.c index 5a4dc428..7d61c13f 100644 --- a/src/libopensc/pkcs15-cert.c +++ b/src/libopensc/pkcs15-cert.c @@ -80,7 +80,7 @@ static int parse_x509_cert(sc_context_t *ctx, const u8 *buf, size_t buflen, stru obj = sc_asn1_verify_tag(ctx, buf, buflen, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, &objlen); if (obj == NULL) { - sc_error(ctx, "X.509 certificate not found\n"); + sc_debug(ctx, "X.509 certificate not found\n"); return SC_ERROR_INVALID_ASN1_OBJECT; } cert->data_len = objlen + (obj - buf); diff --git a/src/libopensc/pkcs15-gemsafeGPK.c b/src/libopensc/pkcs15-gemsafeGPK.c index 44d10486..4064c75e 100644 --- a/src/libopensc/pkcs15-gemsafeGPK.c +++ b/src/libopensc/pkcs15-gemsafeGPK.c @@ -259,14 +259,10 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) path.value[1] = i; path.len = 2; path.type = SC_PATH_TYPE_FILE_ID; - sc_ctx_suppress_errors_on(card->ctx); /* file may not exist, and not an error */ r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) continue; - sc_ctx_suppress_errors_on(card->ctx); r = sc_read_record(card, 1, sysrec, sizeof(sysrec), SC_RECORD_BY_REC_NR); - sc_ctx_suppress_errors_off(card->ctx); if (r != 7 || sysrec[0] != 0) { continue; } @@ -279,7 +275,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card) case 0x10: kinfo[num_keyinfo].modulus_len = 768 / 8; break; case 0x11: kinfo[num_keyinfo].modulus_len = 1024 / 8; break; default: - sc_error(card->ctx, "Unsupported modulus length"); + sc_debug(card->ctx, "Unsupported modulus length"); continue; } diff --git a/src/libopensc/pkcs15-gemsafeV1.c b/src/libopensc/pkcs15-gemsafeV1.c index 9017617b..6bc821ac 100644 --- a/src/libopensc/pkcs15-gemsafeV1.c +++ b/src/libopensc/pkcs15-gemsafeV1.c @@ -144,7 +144,7 @@ static int gemsafe_get_cert_len(sc_card_t *card, sc_path_t *path, sc_debug(card->ctx, "%s: Certificate object is of size: %d\n", fn_name, objlen); if (objlen < 1 || objlen > 10240) { - sc_error(card->ctx, "%s: Invalid object size: %d\n", fn_name, objlen); + sc_debug(card->ctx, "%s: Invalid object size: %d\n", fn_name, objlen); return 0; } @@ -184,7 +184,7 @@ static int gemsafe_get_cert_len(sc_card_t *card, sc_path_t *path, offset = block*248; r = sc_read_binary(card, offset, ibuf, 248, 0); if (r < 0) { - sc_error(card->ctx, "%s: Could not read cert object\n", fn_name); + sc_debug(card->ctx, "%s: Could not read cert object\n", fn_name); return 0; } } @@ -416,7 +416,7 @@ sc_pkcs15emu_add_object(sc_pkcs15_card_t *p15card, int type, df_type = SC_PKCS15_CDF; break; default: - sc_error(p15card->card->ctx, + sc_debug(p15card->card->ctx, "Unknown PKCS15 object type %d\n", type); free(obj); return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/libopensc/pkcs15-infocamere.c b/src/libopensc/pkcs15-infocamere.c index c41c6997..f9d2a40c 100644 --- a/src/libopensc/pkcs15-infocamere.c +++ b/src/libopensc/pkcs15-infocamere.c @@ -242,9 +242,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) sc_format_path("3F002F02", &path); - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, &file); - sc_ctx_suppress_errors_off(card->ctx); if (r != SC_SUCCESS || file->size > 255) { /* Not EF.GDO */ @@ -308,9 +306,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) sc_format_path(infocamere_auth_certpath[ef_gdo[len_iccsn+6]-2], &path); - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r >= 0) { @@ -398,9 +394,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card) sc_format_path(infocamere_cacert_path[ef_gdo[len_iccsn+6]-2], &path); - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r >= 0) { size_t len; @@ -530,7 +524,7 @@ static int loadCertificate(sc_pkcs15_card_t * p15card, int i, sc_read_binary(card, 4, compCert, compLen, 0); if ((r = uncompress(cert, &len, compCert, compLen)) != Z_OK) { - sc_error(p15card->card->ctx, "Zlib error: %d", r); + sc_debug(p15card->card->ctx, "Zlib error: %d", r); return SC_ERROR_INTERNAL; } @@ -614,7 +608,7 @@ static int infocamere_1400_init(sc_pkcs15_card_t * p15card) if ((r = loadCertificate(p15card, 0, certPath[0], certLabel[0])) != SC_SUCCESS) { - sc_error(p15card->card->ctx, "%s", sc_strerror(r)); + sc_debug(p15card->card->ctx, "%s", sc_strerror(r)); return SC_ERROR_WRONG_CARD; } diff --git a/src/libopensc/pkcs15-openpgp.c b/src/libopensc/pkcs15-openpgp.c index 8124b4ed..a5c94017 100644 --- a/src/libopensc/pkcs15-openpgp.c +++ b/src/libopensc/pkcs15-openpgp.c @@ -119,7 +119,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) if ((r = read_file(card, "006E007300C4", buffer, sizeof(buffer))) < 0) goto failed; if (r != 7) { - sc_error(ctx, + sc_debug(ctx, "CHV status bytes have unexpected length " "(expected 7, got %d)\n", r); return SC_ERROR_OBJECT_NOT_VALID; @@ -229,7 +229,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card) return 0; -failed: sc_error(card->ctx, "Failed to initialize OpenPGP emulation: %s\n", +failed: sc_debug(card->ctx, "Failed to initialize OpenPGP emulation: %s\n", sc_strerror(r)); return r; } diff --git a/src/libopensc/pkcs15-piv.c b/src/libopensc/pkcs15-piv.c index 54b4ece0..6310a50c 100644 --- a/src/libopensc/pkcs15-piv.c +++ b/src/libopensc/pkcs15-piv.c @@ -248,9 +248,7 @@ const objdata objects[] = { * but need serial number for Mac tokend */ - sc_ctx_suppress_errors_on(card->ctx); r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) { sc_debug(card->ctx,"sc_card_ctl rc=%d",r); p15card->serial_number = strdup("00000000"); @@ -273,12 +271,10 @@ const objdata objects[] = { /* We could make sure the object is on the card */ /* But really don't need to do this now */ -// sc_ctx_suppress_errors_on(card->ctx); -// r = sc_select_file(card, &obj_info.path, NULL); -// sc_ctx_suppress_errors_off(card->ctx); -// if (r == SC_ERROR_FILE_NOT_FOUND) -// continue; - +/* r = sc_select_file(card, &obj_info.path, NULL); + if (r == SC_ERROR_FILE_NOT_FOUND) + continue; +*/ strncpy(obj_info.app_label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1); r = sc_format_oid(&obj_info.app_oid, objects[i].aoid); if (r != SC_SUCCESS) @@ -330,10 +326,8 @@ const objdata objects[] = { /* see if we have a cert */ /* use a &file_out so card-piv will read cert if present */ - sc_ctx_suppress_errors_on(card->ctx); r = sc_pkcs15_read_file(p15card, &cert_info.path, &cert_der.value, &cert_der.len, &file_out); - sc_ctx_suppress_errors_off(card->ctx); if (file_out) { sc_file_free(file_out); file_out = NULL; @@ -368,7 +362,7 @@ const objdata objects[] = { r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); if (r < 0) { - sc_error(card->ctx, " Failed to add cert obj r=%d",r); + sc_debug(card->ctx, " Failed to add cert obj r=%d",r); continue; } } @@ -441,9 +435,7 @@ const objdata objects[] = { /* TODO DSA */ pubkey_obj.type = SC_PKCS15_TYPE_PUBKEY_RSA; pubkey_obj.data = &pubkey_info; - sc_ctx_suppress_errors_on(card->ctx); r = sc_pkcs15_read_pubkey(p15card, &pubkey_obj, &p15_key); - sc_ctx_suppress_errors_off(card->ctx); pubkey_obj.data = NULL; sc_debug(card->ctx," READING PUB KEY r=%d",r); if (r < 0 ) { diff --git a/src/libopensc/pkcs15-postecert.c b/src/libopensc/pkcs15-postecert.c index 01ef1a33..4ab6f290 100644 --- a/src/libopensc/pkcs15-postecert.c +++ b/src/libopensc/pkcs15-postecert.c @@ -332,7 +332,7 @@ static int sc_pkcs15emu_postecert_init(sc_pkcs15_card_t * p15card) return 0; failed: - sc_error(card->ctx, + sc_debug(card->ctx, "Failed to initialize Postecert and Cnipa emulation: %s\n", sc_strerror(r)); return r; diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index be43412c..e3431af1 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -150,7 +150,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, if (asn1_dsakey_i_p_attr[0].flags & SC_ASN1_PRESENT) info.path.type = SC_PATH_TYPE_PATH_PROT; } else { - sc_error(ctx, "Neither RSA or DSA key in PrKDF entry.\n"); + sc_debug(ctx, "Neither RSA or DSA key in PrKDF entry.\n"); SC_FUNC_RETURN(ctx, 0, SC_ERROR_INVALID_ASN1_OBJECT); } r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); @@ -218,7 +218,7 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx, } break; default: - sc_error(ctx, "Invalid private key type: %X\n", obj->type); + sc_debug(ctx, "Invalid private key type: %X\n", obj->type); SC_FUNC_RETURN(ctx, 0, SC_ERROR_INTERNAL); break; } @@ -281,7 +281,7 @@ sc_pkcs15_encode_prkey(sc_context_t *ctx, { if (key->algorithm == SC_ALGORITHM_DSA) return sc_pkcs15_encode_prkey_dsa(ctx, &key->u.dsa, buf, len); - sc_error(ctx, "Cannot encode private key type %u.\n", + sc_debug(ctx, "Cannot encode private key type %u.\n", key->algorithm); return SC_ERROR_NOT_SUPPORTED; } @@ -293,7 +293,7 @@ sc_pkcs15_decode_prkey(sc_context_t *ctx, { if (key->algorithm == SC_ALGORITHM_DSA) return sc_pkcs15_decode_prkey_dsa(ctx, &key->u.dsa, buf, len); - sc_error(ctx, "Cannot decode private key type %u.\n", + sc_debug(ctx, "Cannot decode private key type %u.\n", key->algorithm); return SC_ERROR_NOT_SUPPORTED; } @@ -321,12 +321,12 @@ sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card, key.algorithm = SC_ALGORITHM_DSA; break; default: - sc_error(ctx, "Unsupported object type.\n"); + sc_debug(ctx, "Unsupported object type.\n"); return SC_ERROR_NOT_SUPPORTED; } info = (struct sc_pkcs15_prkey_info *) obj->data; if (info->native) { - sc_error(ctx, "Private key is native, will not read."); + sc_debug(ctx, "Private key is native, will not read."); return SC_ERROR_NOT_ALLOWED; } @@ -336,7 +336,7 @@ sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card, r = sc_pkcs15_read_file(p15card, &path, &data, &len, NULL); if (r < 0) { - sc_error(ctx, "Unable to read private key file.\n"); + sc_debug(ctx, "Unable to read private key file.\n"); return r; } @@ -354,7 +354,7 @@ sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card, data, len, &clear, &clear_len); if (r < 0) { - sc_error(ctx, "Failed to unwrap privat key."); + sc_debug(ctx, "Failed to unwrap privat key."); goto fail; } free(data); @@ -364,7 +364,7 @@ sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card, r = sc_pkcs15_decode_prkey(ctx, &key, data, len); if (r < 0) { - sc_error(ctx, "Unable to decode private key"); + sc_debug(ctx, "Unable to decode private key"); goto fail; } diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 3e32033e..ab619f91 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -192,7 +192,7 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx, sc_format_asn1_entry(asn1_dsakey_attr + 0, &pubkey->path, NULL, 1); break; default: - sc_error(ctx, "Unsupported public key type: %X\n", obj->type); + sc_debug(ctx, "Unsupported public key type: %X\n", obj->type); SC_FUNC_RETURN(ctx, 0, SC_ERROR_INTERNAL); break; } @@ -350,7 +350,7 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx, return sc_pkcs15_encode_pubkey_rsa(ctx, &key->u.rsa, buf, len); if (key->algorithm == SC_ALGORITHM_DSA) return sc_pkcs15_encode_pubkey_dsa(ctx, &key->u.dsa, buf, len); - sc_error(ctx, "Encoding of public key type %u not supported\n", + sc_debug(ctx, "Encoding of public key type %u not supported\n", key->algorithm); return SC_ERROR_NOT_SUPPORTED; } @@ -364,7 +364,7 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx, return sc_pkcs15_decode_pubkey_rsa(ctx, &key->u.rsa, buf, len); if (key->algorithm == SC_ALGORITHM_DSA) return sc_pkcs15_decode_pubkey_dsa(ctx, &key->u.dsa, buf, len); - sc_error(ctx, "Decoding of public key type %u not supported\n", + sc_debug(ctx, "Decoding of public key type %u not supported\n", key->algorithm); return SC_ERROR_NOT_SUPPORTED; } @@ -394,14 +394,14 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, algorithm = SC_ALGORITHM_DSA; break; default: - sc_error(p15card->card->ctx, "Unsupported public key type."); + sc_debug(p15card->card->ctx, "Unsupported public key type."); return SC_ERROR_NOT_SUPPORTED; } info = (const struct sc_pkcs15_pubkey_info *) obj->data; r = sc_pkcs15_read_file(p15card, &info->path, &data, &len, NULL); if (r < 0) { - sc_error(p15card->card->ctx, "Failed to read public key file."); + sc_debug(p15card->card->ctx, "Failed to read public key file."); return r; } diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 86ec3f42..69246265 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -77,13 +77,13 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, return SC_ERROR_EXTRACTABLE_KEY; if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP))) { - sc_error(ctx, "This key cannot be used for decryption\n"); + sc_debug(ctx, "This key cannot be used for decryption\n"); return SC_ERROR_NOT_ALLOWED; } alg_info = _sc_card_find_rsa_alg(p15card->card, prkey->modulus_length); if (alg_info == NULL) { - sc_error(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length); + sc_debug(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length); return SC_ERROR_NOT_SUPPORTED; } senv.algorithm = SC_ALGORITHM_RSA; @@ -157,7 +157,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, in, inlen, out, outlen); } if (modlen > tmplen) { - sc_error(ctx, "Buffer too small, needs recompile!\n"); + sc_debug(ctx, "Buffer too small, needs recompile!\n"); return SC_ERROR_NOT_ALLOWED; } r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, modlen); @@ -180,13 +180,13 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_SIGNRECOVER| SC_PKCS15_PRKEY_USAGE_NONREPUDIATION))) { - sc_error(ctx, "This key cannot be used for signing\n"); + sc_debug(ctx, "This key cannot be used for signing\n"); return SC_ERROR_NOT_ALLOWED; } alg_info = _sc_card_find_rsa_alg(p15card->card, prkey->modulus_length); if (alg_info == NULL) { - sc_error(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length); + sc_debug(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length); return SC_ERROR_NOT_SUPPORTED; } senv.algorithm = SC_ALGORITHM_RSA; diff --git a/src/libopensc/pkcs15-starcert.c b/src/libopensc/pkcs15-starcert.c index b72265cb..7dfb48f5 100644 --- a/src/libopensc/pkcs15-starcert.c +++ b/src/libopensc/pkcs15-starcert.c @@ -105,9 +105,7 @@ static int starcert_detect_card(sc_pkcs15_card_t *p15card) return SC_ERROR_WRONG_CARD; /* read EF_Info file */ sc_format_path("3F00FE13", &path); - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r != SC_SUCCESS) return SC_ERROR_WRONG_CARD; r = sc_read_binary(card, 0, buf, 64, 0); diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 801f747c..b66f7ea2 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -178,7 +178,7 @@ out: if (r == SC_SUCCESS) { p15card->magic = SC_PKCS15_CARD_MAGIC; p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED; } else if (r != SC_ERROR_WRONG_CARD) { - sc_error(ctx, "Failed to load card emulator: %s\n", + sc_debug(ctx, "Failed to load card emulator: %s\n", sc_strerror(r)); } @@ -400,7 +400,7 @@ int sc_pkcs15emu_object_add(sc_pkcs15_card_t *p15card, unsigned int type, data_len = sizeof(struct sc_pkcs15_data_info); break; default: - sc_error(p15card->card->ctx, + sc_debug(p15card->card->ctx, "Unknown PKCS15 object type %d\n", type); free(obj); return SC_ERROR_INVALID_ARGUMENTS; diff --git a/src/libopensc/pkcs15-tcos.c b/src/libopensc/pkcs15-tcos.c index 3c960ef7..6a98fabc 100644 --- a/src/libopensc/pkcs15-tcos.c +++ b/src/libopensc/pkcs15-tcos.c @@ -455,14 +455,10 @@ int sc_pkcs15emu_tcos_init_ex( serial[19] = '\0'; p15card->serial_number = strdup(serial); - sc_ctx_suppress_errors_on(ctx); - if(!detect_netkey(p15card)) return SC_SUCCESS; if(!detect_signtrust(p15card)) return SC_SUCCESS; if(!detect_datev(p15card)) return SC_SUCCESS; if(!detect_unicard(p15card)) return SC_SUCCESS; - sc_ctx_suppress_errors_off(ctx); - return SC_ERROR_INTERNAL; } diff --git a/src/libopensc/pkcs15-wrap.c b/src/libopensc/pkcs15-wrap.c index b99e864c..d331e4b2 100644 --- a/src/libopensc/pkcs15-wrap.c +++ b/src/libopensc/pkcs15-wrap.c @@ -78,7 +78,7 @@ sc_pkcs15_derive_key(sc_context_t *ctx, /* XXX: We might also encounter PBES2 here */ if (der_alg->algorithm != SC_ALGORITHM_PBKDF2) { - sc_error(ctx, "Unsupported key derivation algorithm.\n"); + sc_debug(ctx, "Unsupported key derivation algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -92,27 +92,27 @@ sc_pkcs15_derive_key(sc_context_t *ctx, iv = (u8 *) enc_alg->params; break; default: - sc_error(ctx, "Unsupported key encryption algorithm.\n"); + sc_debug(ctx, "Unsupported key encryption algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; } if (!iv) { - sc_error(ctx, "Unsupported key encryption parameters.\n"); + sc_debug(ctx, "Unsupported key encryption parameters.\n"); return SC_ERROR_NOT_SUPPORTED; } key_len = EVP_CIPHER_key_length(cipher); info = (struct sc_pbkdf2_params *) der_alg->params; if (!info) { - sc_error(ctx, "Key parameters missing.\n"); + sc_debug(ctx, "Key parameters missing.\n"); return SC_ERROR_INVALID_ARGUMENTS; } if (info->key_length && info->key_length != key_len) { - sc_error(ctx, "Incompatible key length.\n"); + sc_debug(ctx, "Incompatible key length.\n"); return SC_ERROR_INVALID_ARGUMENTS; } if (key_len > sizeof(key)) { - sc_error(ctx, "Huge key length (%u).\n", key_len); + sc_debug(ctx, "Huge key length (%u).\n", key_len); return SC_ERROR_INVALID_ARGUMENTS; } @@ -120,7 +120,7 @@ sc_pkcs15_derive_key(sc_context_t *ctx, info->salt, info->salt_len, info->iterations, key_len, key); if (r == 0) { - sc_error(ctx, "Key derivation failed.\n"); + sc_debug(ctx, "Key derivation failed.\n"); return SC_ERROR_INTERNAL; /* for lack of something better */ } @@ -223,7 +223,7 @@ sc_pkcs15_unwrap_data(sc_context_t *ctx, memset(&envdata, 0, sizeof(envdata)); r = sc_pkcs15_decode_enveloped_data(ctx, &envdata, in, in_len); if (r < 0) { - sc_error(ctx, "Failed to decode EnvelopedData.\n"); + sc_debug(ctx, "Failed to decode EnvelopedData.\n"); return r; } diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 8e6ec5c2..ad70a491 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -95,7 +95,7 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx, r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL); if (r) { - sc_error(ctx, "ASN.1 parsing of EF(TokenInfo) failed: %s\n", + sc_debug(ctx, "ASN.1 parsing of EF(TokenInfo) failed: %s\n", sc_strerror(r)); return r; } @@ -196,7 +196,7 @@ int sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, r = sc_asn1_encode(ctx, asn1_tokeninfo, buf, buflen); if (r) { - sc_error(ctx, "sc_asn1_encode() failed: %s\n", sc_strerror(r)); + sc_debug(ctx, "sc_asn1_encode() failed: %s\n", sc_strerror(r)); return r; } return 0; @@ -223,7 +223,7 @@ static int parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t bufl r = sc_asn1_decode(p15card->card->ctx, asn1_ddo, buf, buflen, NULL, NULL); if (r) { - sc_error(p15card->card->ctx, "DDO parsing failed: %s\n", + sc_debug(p15card->card->ctx, "DDO parsing failed: %s\n", sc_strerror(r)); return r; } @@ -276,7 +276,7 @@ static int encode_ddo(struct sc_pkcs15_card *p15card, u8 **buf, size_t *buflen) r = sc_asn1_encode(ctx, asn1_dir, buf, buflen); if (r) { - sc_error(ctx, "sc_asn1_encode() failed: %s\n", + sc_debug(ctx, "sc_asn1_encode() failed: %s\n", sc_strerror(r)); return r; } @@ -362,7 +362,7 @@ int sc_pkcs15_encode_odf(sc_context_t *ctx, df = df->next; }; if (df_count == 0) { - sc_error(ctx, "No DF's found.\n"); + sc_debug(ctx, "No DF's found.\n"); return SC_ERROR_OBJECT_NOT_FOUND; } asn1_odf = (struct sc_asn1_entry *) malloc(sizeof(struct sc_asn1_entry) * (df_count + 1)); @@ -384,7 +384,7 @@ int sc_pkcs15_encode_odf(sc_context_t *ctx, break; } if (type == -1) { - sc_error(ctx, "Unsupported DF type.\n"); + sc_debug(ctx, "Unsupported DF type.\n"); continue; } asn1_odf[c] = c_asn1_odf[type]; @@ -529,7 +529,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) if (card->app_count < 0) { err = sc_enum_apps(card); if (err < 0 && err != SC_ERROR_FILE_NOT_FOUND) { - sc_error(ctx, "unable to enumerate apps: %s\n", sc_strerror(err)); + sc_debug(ctx, "unable to enumerate apps: %s\n", sc_strerror(err)); goto end; } } @@ -552,7 +552,6 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) } /* Check if pkcs15 directory exists */ - sc_ctx_suppress_errors_on(card->ctx); err = sc_select_file(card, &p15card->file_app->path, NULL); #if 1 /* If the above test failed on cards without EF(DIR), @@ -564,18 +563,15 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) err = SC_NO_ERROR; } #endif - sc_ctx_suppress_errors_off(card->ctx); if (err < 0) goto end; if (p15card->file_odf == NULL) { /* check if an ODF is present; suppress errors as we - * don't know yet whether we have a pkcs15 card */ + * don't know yet whether we have a pkcs15 card */ tmppath = p15card->file_app->path; sc_append_path_id(&tmppath, (const u8 *) "\x50\x31", 2); - sc_ctx_suppress_errors_on(card->ctx); err = sc_select_file(card, &tmppath, &p15card->file_odf); - sc_ctx_suppress_errors_off(card->ctx); } else { tmppath = p15card->file_odf->path; @@ -595,7 +591,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) } if ((len = p15card->file_odf->size) == 0) { - sc_error(card->ctx, "EF(ODF) is empty\n"); + sc_debug(card->ctx, "EF(ODF) is empty\n"); goto end; } buf = malloc(len); @@ -611,7 +607,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) len = err; if (parse_odf(buf, len, p15card)) { err = SC_ERROR_PKCS15_APP_NOT_FOUND; - sc_error(card->ctx, "Unable to parse ODF\n"); + sc_debug(card->ctx, "Unable to parse ODF\n"); goto end; } free(buf); @@ -647,7 +643,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) goto end; if ((len = p15card->file_tokeninfo->size) == 0) { - sc_error(card->ctx, "EF(TokenInfo) is empty\n"); + sc_debug(card->ctx, "EF(TokenInfo) is empty\n"); goto end; } buf = malloc(len); @@ -717,7 +713,7 @@ int sc_pkcs15_bind(sc_card_t *card, r = sc_lock(card); if (r) { - sc_error(ctx, "sc_lock() failed: %s\n", sc_strerror(r)); + sc_debug(ctx, "sc_lock() failed: %s\n", sc_strerror(r)); sc_pkcs15_card_free(p15card); SC_FUNC_RETURN(ctx, 1, r); } @@ -1362,7 +1358,7 @@ int sc_pkcs15_encode_df(sc_context_t *ctx, break; } if (func == NULL) { - sc_error(ctx, "unknown DF type: %d\n", df->type); + sc_debug(ctx, "unknown DF type: %d\n", df->type); *buf_out = NULL; *bufsize_out = 0; return 0; @@ -1419,7 +1415,7 @@ int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, break; } if (func == NULL) { - sc_error(ctx, "unknown DF type: %d\n", df->type); + sc_debug(ctx, "unknown DF type: %d\n", df->type); return SC_ERROR_INVALID_ARGUMENTS; } if (df->file != NULL) @@ -1489,7 +1485,7 @@ int sc_pkcs15_add_unusedspace(struct sc_pkcs15_card *p15card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_error(p15card->card->ctx, "No offset and length present in path %s\n", pbuf); + sc_debug(p15card->card->ctx, "No offset and length present in path %s\n", pbuf); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1712,10 +1708,8 @@ int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, for (i=1; ; i++) { l = len - (head - data); if (l > 256) { l = 256; } - p15card->card->ctx->suppress_errors++; r = sc_read_record(p15card->card, i, head, l, SC_RECORD_BY_REC_NR); - p15card->card->ctx->suppress_errors--; if (r == SC_ERROR_RECORD_NOT_FOUND) break; if (r < 0) { diff --git a/src/libopensc/reader-ctapi.c b/src/libopensc/reader-ctapi.c index a3e16ea0..857f8687 100644 --- a/src/libopensc/reader-ctapi.c +++ b/src/libopensc/reader-ctapi.c @@ -96,11 +96,11 @@ static int ctapi_reset(sc_reader_t *reader, sc_slot_info_t *slot) rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf); if (rv || (lr < 2)) { - sc_error(reader->ctx, "Error getting status of terminal: %d, using defaults\n", rv); + sc_debug(reader->ctx, "Error getting status of terminal: %d, using defaults\n", rv); return SC_ERROR_TRANSMIT_FAILED; } if (rbuf[lr-2] != 0x90) { - sc_error(reader->ctx, "SW1/SW2: 0x%x/0x%x\n", rbuf[lr-2], rbuf[lr-1]); + sc_debug(reader->ctx, "SW1/SW2: 0x%x/0x%x\n", rbuf[lr-2], rbuf[lr-1]); return SC_ERROR_TRANSMIT_FAILED; } return 0; @@ -141,7 +141,7 @@ static void detect_functional_units(sc_reader_t *reader) rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf); if (rv || (lr < 4) || (rbuf[lr-2] != 0x90)) { - sc_error(reader->ctx, "Error getting status of terminal: %d, using defaults\n", rv); + sc_debug(reader->ctx, "Error getting status of terminal: %d, using defaults\n", rv); set_default_fu(reader); return; } @@ -149,13 +149,13 @@ static void detect_functional_units(sc_reader_t *reader) /* Number of slots might also detected by using CTBCS_P2_STATUS_ICC. If you think that's important please do it... ;) */ set_default_fu(reader); - sc_error(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_TFU: 0x%x\n", rbuf[0]); + sc_debug(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_TFU: 0x%x\n", rbuf[0]); return; } NumUnits = rbuf[1]; if (NumUnits + 4 > lr) { set_default_fu(reader); - sc_error(reader->ctx, "Invalid data returnd: %d functional units, size %d\n", NumUnits, rv); + sc_debug(reader->ctx, "Invalid data returnd: %d functional units, size %d\n", NumUnits, rv); set_default_fu(reader); return; } @@ -257,13 +257,13 @@ static int refresh_slot_attributes(sc_reader_t *reader, rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf); if (rv || (lr < 3) || (rbuf[lr-2] != 0x90)) { - sc_error(reader->ctx, "Error getting status of terminal: %d/%d/0x%x\n", rv, lr, rbuf[lr-2]); + sc_debug(reader->ctx, "Error getting status of terminal: %d/%d/0x%x\n", rv, lr, rbuf[lr-2]); return SC_ERROR_TRANSMIT_FAILED; } if (lr < 4) { /* Looks like older readers do not return data tag and length field, so assume one slot only */ if (slot->id > 0) { - sc_error(reader->ctx, "Status for slot id %d not returned, have only 1\n", slot->id); + sc_debug(reader->ctx, "Status for slot id %d not returned, have only 1\n", slot->id); return SC_ERROR_SLOT_NOT_FOUND; } if (rbuf[0] & CTBCS_DATA_STATUS_CARD) @@ -271,11 +271,11 @@ static int refresh_slot_attributes(sc_reader_t *reader, } else { if (rbuf[0] != CTBCS_P2_STATUS_ICC) { /* Should we be more tolerant here? I do not think so... */ - sc_error(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_ICC: 0x%x\n", rbuf[0]); + sc_debug(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_ICC: 0x%x\n", rbuf[0]); return SC_ERROR_TRANSMIT_FAILED; } if (rbuf[1] <= slot->id) { - sc_error(reader->ctx, "Status for slot id %d not returned, only %d\n", slot->id, rbuf[1]); + sc_debug(reader->ctx, "Status for slot id %d not returned, only %d\n", slot->id, rbuf[1]); return SC_ERROR_SLOT_NOT_FOUND; } if (rbuf[2+slot->id] & CTBCS_DATA_STATUS_CARD) @@ -306,7 +306,7 @@ static int ctapi_internal_transmit(sc_reader_t *reader, sc_slot_info_t *slot, rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, (unsigned short)sendsize, (u8 *) sendbuf, &lr, recvbuf); if (rv != 0) { - sc_error(reader->ctx, "Error transmitting APDU: %d\n", rv); + sc_debug(reader->ctx, "Error transmitting APDU: %d\n", rv); return SC_ERROR_TRANSMIT_FAILED; } *recvsize = lr; @@ -337,7 +337,7 @@ static int ctapi_transmit(sc_reader_t *reader, sc_slot_info_t *slot, rbuf, &rsize, apdu->control); if (r < 0) { /* unable to transmit ... most likely a reader problem */ - sc_error(reader->ctx, "unable to transmit"); + sc_debug(reader->ctx, "unable to transmit"); goto out; } if (reader->ctx->debug >= 6) @@ -386,7 +386,7 @@ static int ctapi_connect(sc_reader_t *reader, sc_slot_info_t *slot) rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf); if (rv || rbuf[lr-2] != 0x90) { - sc_error(reader->ctx, "Error activating card: %d\n", rv); + sc_debug(reader->ctx, "Error activating card: %d\n", rv); return SC_ERROR_TRANSMIT_FAILED; } if (lr < 2) @@ -413,7 +413,7 @@ static int ctapi_connect(sc_reader_t *reader, sc_slot_info_t *slot) rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 9, cmd, &lr, rbuf); if (rv) { - sc_error(reader->ctx, "Error negotiating PPS: %d\n", rv); + sc_debug(reader->ctx, "Error negotiating PPS: %d\n", rv); return SC_ERROR_TRANSMIT_FAILED; } } @@ -483,14 +483,14 @@ static int ctapi_load_module(sc_context_t *ctx, list = scconf_find_list(conf, "ports"); if (list == NULL) { - sc_error(ctx, "No ports configured.\n"); + sc_debug(ctx, "No ports configured.\n"); return -1; } val = conf->name->data; dlh = lt_dlopen(val); if (!dlh) { - sc_error(ctx, "Unable to open shared library '%s': %s\n", val, lt_dlerror()); + sc_debug(ctx, "Unable to open shared library '%s': %s\n", val, lt_dlerror()); return -1; } @@ -513,12 +513,12 @@ static int ctapi_load_module(sc_context_t *ctx, struct ctapi_private_data *priv; if (sscanf(list->data, "%d", &port) != 1) { - sc_error(ctx, "Port '%s' is not a number.\n", list->data); + sc_debug(ctx, "Port '%s' is not a number.\n", list->data); continue; } rv = funcs.CT_init((unsigned short)mod->ctn_count, (unsigned short)port); if (rv) { - sc_error(ctx, "CT_init() failed with %d\n", rv); + sc_debug(ctx, "CT_init() failed with %d\n", rv); continue; } reader = (sc_reader_t *) calloc(1, sizeof(sc_reader_t)); @@ -550,7 +550,7 @@ static int ctapi_load_module(sc_context_t *ctx, } return 0; symerr: - sc_error(ctx, "Unable to resolve CT-API symbols.\n"); + sc_debug(ctx, "Unable to resolve CT-API symbols.\n"); lt_dlclose(dlh); return -1; } diff --git a/src/libopensc/reader-openct.c b/src/libopensc/reader-openct.c index b0eb9a8a..1054454d 100644 --- a/src/libopensc/reader-openct.c +++ b/src/libopensc/reader-openct.c @@ -221,21 +221,21 @@ openct_reader_connect(sc_reader_t *reader, ct_reader_disconnect(data->h); if (!(data->h = ct_reader_connect(data->num))) { - sc_error(reader->ctx, "ct_reader_connect socket failed\n"); + sc_debug(reader->ctx, "ct_reader_connect socket failed\n"); return SC_ERROR_CARD_NOT_PRESENT; } rc = ct_card_request(data->h, slot->id, 0, NULL, slot->atr, sizeof(slot->atr)); if (rc < 0) { - sc_error(reader->ctx, + sc_debug(reader->ctx, "openct_reader_connect read failed: %s\n", ct_strerror(rc)); return SC_ERROR_CARD_NOT_PRESENT; } if (rc == 0) { - sc_error(reader->ctx, "openct_reader_connect recved no data\n"); + sc_debug(reader->ctx, "openct_reader_connect recved no data\n"); return SC_ERROR_READER; } @@ -321,7 +321,7 @@ static int openct_reader_transmit(sc_reader_t *reader, sc_slot_info_t *slot, rbuf, &rsize, apdu->control); if (r < 0) { /* unable to transmit ... most likely a reader problem */ - sc_error(reader->ctx, "unable to transmit"); + sc_debug(reader->ctx, "unable to transmit"); goto out; } if (reader->ctx->debug >= 6) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index add702a8..b6abdbbf 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -39,7 +39,7 @@ #undef SCARD_PROTOCOL_ANY #define SCARD_PROTOCOL_ANY (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) /* Error printing */ -#define PCSC_ERROR(ctx, desc, rv) sc_error(ctx, desc ": 0x%08lx\n", rv); +#define PCSC_ERROR(ctx, desc, rv) sc_debug(ctx, desc ": 0x%08lx\n", rv); /* Utility for handling big endian IOCTL codes. */ #define dw2i_be(a, x) ((((((a[x] << 8) + a[x+1]) << 8) + a[x+2]) << 8) + a[x+3]) @@ -236,7 +236,7 @@ static int pcsc_transmit(sc_reader_t *reader, sc_slot_info_t *slot, rbuf, &rsize, apdu->control); if (r < 0) { /* unable to transmit ... most likely a reader problem */ - sc_error(reader->ctx, "unable to transmit"); + sc_debug(reader->ctx, "unable to transmit"); goto out; } if (reader->ctx->debug >= 6) @@ -1282,7 +1282,7 @@ part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, /* The APDU must be provided by the card driver */ if (!data->apdu) { - sc_error(reader->ctx, "No APDU provided for PC/SC v2 pinpad verification!"); + sc_debug(reader->ctx, "No APDU provided for PC/SC v2 pinpad verification!"); return SC_ERROR_NOT_SUPPORTED; } @@ -1290,7 +1290,7 @@ part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, switch (data->cmd) { case SC_PIN_CMD_VERIFY: if (!(pslot->verify_ioctl || (pslot->verify_ioctl_start && pslot->verify_ioctl_finish))) { - sc_error(reader->ctx, "Pinpad reader does not support verification!"); + sc_debug(reader->ctx, "Pinpad reader does not support verification!"); return SC_ERROR_NOT_SUPPORTED; } r = part10_build_verify_pin_block(sbuf, &scount, slot, data); @@ -1299,14 +1299,14 @@ part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, case SC_PIN_CMD_CHANGE: case SC_PIN_CMD_UNBLOCK: if (!(pslot->modify_ioctl || (pslot->modify_ioctl_start && pslot->modify_ioctl_finish))) { - sc_error(reader->ctx, "Pinpad reader does not support modification!"); + sc_debug(reader->ctx, "Pinpad reader does not support modification!"); return SC_ERROR_NOT_SUPPORTED; } r = part10_build_modify_pin_block(sbuf, &scount, slot, data); ioctl = pslot->modify_ioctl ? pslot->modify_ioctl : pslot->modify_ioctl_start; break; default: - sc_error(reader->ctx, "Unknown PIN command %d", data->cmd); + sc_debug(reader->ctx, "Unknown PIN command %d", data->cmd); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 485d1ea1..500a64b3 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -660,12 +660,12 @@ int _sc_parse_atr(sc_context_t *ctx, sc_slot_info_t *slot) slot->atr_info.hist_bytes = NULL; if (atr_len == 0) { - sc_error(ctx, "empty ATR - card not present?\n"); + sc_debug(ctx, "empty ATR - card not present?\n"); return SC_ERROR_INTERNAL; } if (p[0] != 0x3B && p[0] != 0x3F) { - sc_error(ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]); + sc_debug(ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]); return SC_ERROR_INTERNAL; } n_hist = p[1] & 0x0F; diff --git a/src/libopensc/sec.c b/src/libopensc/sec.c index 33d65df6..ed06624a 100644 --- a/src/libopensc/sec.c +++ b/src/libopensc/sec.c @@ -192,10 +192,10 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, break; } if (r == SC_ERROR_NOT_SUPPORTED) - sc_error(card->ctx, "unsupported PIN operation (%d)", + sc_debug(card->ctx, "unsupported PIN operation (%d)", data->cmd); } else { - sc_error(card->ctx, "Use of pin pad not supported by card driver"); + sc_debug(card->ctx, "Use of pin pad not supported by card driver"); r = SC_ERROR_NOT_SUPPORTED; } SC_FUNC_RETURN(card->ctx, 2, r); diff --git a/src/libopensc/ui.c b/src/libopensc/ui.c index 8538b9ab..e743b8a4 100644 --- a/src/libopensc/ui.c +++ b/src/libopensc/ui.c @@ -182,7 +182,7 @@ static int sc_ui_get_func(sc_context_t *ctx, const char *name, void **ret) sc_ui_lib_handle = lt_dlopen(lib_name); if (!sc_ui_lib_handle) { - sc_error(ctx, + sc_debug(ctx, "Unable to open user interface library '%s': %s\n", lib_name, lt_dlerror()); return SC_ERROR_INTERNAL; @@ -391,10 +391,6 @@ sc_ui_display_msg(sc_context_t *ctx, int type, const char *msg) int n; switch (type) { - case SC_LOG_TYPE_ERROR: - outf = ctx->error_file; - break; - case SC_LOG_TYPE_DEBUG: outf = ctx->debug_file; break; diff --git a/src/pkcs11/framework-pkcs15init.c b/src/pkcs11/framework-pkcs15init.c index ac071bd9..c8dd0571 100644 --- a/src/pkcs11/framework-pkcs15init.c +++ b/src/pkcs11/framework-pkcs15init.c @@ -33,9 +33,7 @@ static CK_RV pkcs15init_bind(struct sc_pkcs11_card *p11card) struct sc_profile *profile; int rc; - sc_ctx_suppress_errors_on(card->ctx); rc = sc_pkcs15init_bind(card, "pkcs15", NULL, &profile); - sc_ctx_suppress_errors_off(card->ctx); if (rc == 0) p11card->fw_data = profile; return sc_to_cryptoki_error(rc, p11card->reader); diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 87e465b4..d6278bd8 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -187,7 +187,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) #endif if (context != NULL) { - sc_error(context, "C_Initialize(): Cryptoki already initialized\n"); + sc_debug(context, "C_Initialize(): Cryptoki already initialized\n"); return CKR_CRYPTOKI_ALREADY_INITIALIZED; } @@ -627,7 +627,7 @@ again: return rv; if (r != SC_SUCCESS) { - sc_error(context, "sc_wait_for_event() returned %d\n", r); + sc_debug(context, "sc_wait_for_event() returned %d\n", r); rv = sc_to_cryptoki_error(r, -1); goto out; } diff --git a/src/pkcs15init/pkcs15-asepcos.c b/src/pkcs15init/pkcs15-asepcos.c index a85bea9d..956d1845 100644 --- a/src/pkcs15init/pkcs15-asepcos.c +++ b/src/pkcs15init/pkcs15-asepcos.c @@ -37,9 +37,7 @@ static int asepcos_cond_delete(sc_profile_t *pro, sc_card_t *card, int r; sc_file_t *tfile = NULL; - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, path, &tfile); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_SUCCESS) { r = sc_pkcs15init_authenticate(pro, card, tfile, SC_AC_OP_DELETE_SELF); sc_file_free(tfile); @@ -64,9 +62,7 @@ static int asepcos_check_verify_tpin(sc_profile_t *profile, sc_card_t *card) sc_path_t path; /* check whether the file with the transport PIN exists */ sc_format_path("3f000001", &path); - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_SUCCESS) { /* try to verify the transport key */ u8 pbuf[64]; @@ -84,18 +80,18 @@ static int asepcos_check_verify_tpin(sc_profile_t *profile, sc_card_t *card) card->caps |= SC_CARD_CAP_USE_FCI_AC; sc_file_free(tfile); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to authenticate"); + sc_debug(card->ctx, "unable to authenticate"); return r; } /* store the transport key as a PIN */ r = sc_keycache_get_key(&path, SC_AC_AUT, 0, pbuf, psize); if (r < 0) { - sc_error(card->ctx, "unable to get transport key"); + sc_debug(card->ctx, "unable to get transport key"); return r; } r = sc_keycache_put_key(&path, SC_AC_CHV, 0, pbuf, (size_t)r); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to store transport key"); + sc_debug(card->ctx, "unable to store transport key"); return r; } } @@ -219,7 +215,7 @@ static int asepcos_pinid_to_akn(sc_card_t *card, int fileid, int *akn) if (r != SC_SUCCESS) return r; if (nfile->prop_attr == NULL || nfile->prop_attr_len != 11) { - sc_error(card->ctx, "unable to determine AKN"); + sc_debug(card->ctx, "unable to determine AKN"); sc_file_free(nfile); return SC_ERROR_INTERNAL; } @@ -244,7 +240,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card, *p++ = pinid & 0xff; /* pin length */ if (pinlen < 4 || pinlen > 16) { - sc_error(card->ctx, "invalid PIN length"); + sc_debug(card->ctx, "invalid PIN length"); return SC_ERROR_INVALID_ARGUMENTS; } *p++ = 0x00; @@ -310,7 +306,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card, r = sc_create_file(card, nfile); sc_file_free(nfile); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to create PIN file"); + sc_debug(card->ctx, "unable to create PIN file"); return r; } /* get AKN of the newly created PIN */ @@ -380,7 +376,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_card_t *card, r = sc_pkcs15init_authenticate(profile, card, tfile, SC_AC_OP_CREATE); sc_file_free(tfile); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to create PIN file, insufficent rights"); + sc_debug(card->ctx, "unable to create PIN file, insufficent rights"); return r; } @@ -393,13 +389,11 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_card_t *card, r = sc_append_file_id(&pin_path, pid & 0xff); if (r != SC_SUCCESS) return r; - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &pin_path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_SUCCESS) pid += 2; else if (r != SC_ERROR_FILE_NOT_FOUND) { - sc_error(card->ctx, "error selecting PIN file"); + sc_debug(card->ctx, "error selecting PIN file"); return r; } } while (r != SC_ERROR_FILE_NOT_FOUND); @@ -452,7 +446,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_card_t *card, return r; r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_SET_SATTR, df); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to change the security attributes"); + sc_debug(card->ctx, "unable to change the security attributes"); return r; } /* finally activate the application DF (fix ACLs) */ @@ -465,7 +459,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_card_t *card, st.is_ef = 0; r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_ACTIVATE_FILE, &st); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to activate DF"); + sc_debug(card->ctx, "unable to activate DF"); return r; } } @@ -497,14 +491,14 @@ static int asepcos_do_authenticate(sc_profile_t *profile, sc_card_t *card, sc_file_t *prkey = NULL; r = sc_profile_get_file_by_path(profile, path, &prkey); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to find file in profile"); + sc_debug(card->ctx, "unable to find file in profile"); return r; } r = sc_pkcs15init_authenticate(profile, card, prkey, op); sc_file_free(prkey); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to authenticate"); + sc_debug(card->ctx, "unable to authenticate"); return r; } return SC_SUCCESS; @@ -565,7 +559,7 @@ static int asepcos_do_create_key(sc_card_t *card, size_t ksize, int fileid, nfile->id = fileid & 0xffff; r = sc_file_set_prop_attr(nfile, buf, p - buf); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to set key prop. attributes"); + sc_debug(card->ctx, "unable to set key prop. attributes"); sc_file_free(nfile); return r; } @@ -573,7 +567,7 @@ static int asepcos_do_create_key(sc_card_t *card, size_t ksize, int fileid, r = sc_create_file(card, nfile); sc_file_free(nfile); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to create key file"); + sc_debug(card->ctx, "unable to create key file"); return r; } return r; @@ -599,7 +593,7 @@ static int asepcos_create_key(sc_profile_t *profile, sc_card_t *card, st.akn = sc_keycache_find_named_pin(NULL, SC_PKCS15INIT_USER_PIN); r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_AKN2FILEID, &st); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to determine file id of the PIN"); + sc_debug(card->ctx, "unable to determine file id of the PIN"); return r; } afileid = st.fileid; @@ -664,7 +658,7 @@ static int asepcos_create_key(sc_profile_t *profile, sc_card_t *card, r = asepcos_do_create_key(card, kinfo->modulus_length, fileid, buf, p - buf); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to create private key file"); + sc_debug(card->ctx, "unable to create private key file"); return r; } return r; @@ -695,7 +689,7 @@ static int asepcos_do_store_rsa_key(sc_card_t *card, sc_profile_t *profile, tpath.value[1] = kinfo->path.value[kinfo->path.len-1]; r = sc_select_file(card, &tpath, NULL); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to select rsa key file"); + sc_debug(card->ctx, "unable to select rsa key file"); return r; } @@ -734,7 +728,7 @@ static int asepcos_do_store_rsa_key(sc_card_t *card, sc_profile_t *profile, r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_CHANGE_KEY, &ckdata); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to change key data"); + sc_debug(card->ctx, "unable to change key data"); return r; } @@ -754,7 +748,7 @@ static int asepcos_store_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "only RSA is currently supported"); + sc_debug(card->ctx, "only RSA is currently supported"); return SC_ERROR_NOT_SUPPORTED; } @@ -790,7 +784,7 @@ static int asepcos_generate_key(sc_profile_t *profile, sc_card_t *card, tpath.value[1] = kinfo->path.value[kinfo->path.len-1]; r = sc_select_file(card, &tpath, NULL); if (r != SC_SUCCESS) { - sc_error(card->ctx, "unable to select rsa key file"); + sc_debug(card->ctx, "unable to select rsa key file"); return r; } @@ -809,7 +803,7 @@ static int asepcos_generate_key(sc_profile_t *profile, sc_card_t *card, r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { - sc_error(card->ctx, "error creating key"); + sc_debug(card->ctx, "error creating key"); return SC_ERROR_INTERNAL; } diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 40f61a86..72b014de 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -256,12 +256,12 @@ cardos_store_key(sc_profile_t *profile, sc_card_t *card, int algorithm, r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "CardOS supports RSA keys only."); + sc_debug(card->ctx, "CardOS supports RSA keys only."); return SC_ERROR_NOT_SUPPORTED; } if (cardos_key_algorithm(key_info->usage, key_info->modulus_length, &algorithm) < 0) { - sc_error(card->ctx, "CardOS does not support keys " + sc_debug(card->ctx, "CardOS does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } @@ -316,7 +316,7 @@ cardos_generate_key(sc_profile_t *profile, sc_card_t *card, rsa_max_size = (card->caps & SC_CARD_CAP_RSA_2048) ? 2048 : 1024; keybits = key_info->modulus_length & ~7UL; if (keybits > rsa_max_size) { - sc_error(card->ctx, "Unable to generate key, max size is %lu", + sc_debug(card->ctx, "Unable to generate key, max size is %lu", (unsigned long) rsa_max_size); return SC_ERROR_INVALID_ARGUMENTS; } @@ -325,13 +325,13 @@ cardos_generate_key(sc_profile_t *profile, sc_card_t *card, use_ext_rsa = 1; if (cardos_key_algorithm(key_info->usage, keybits, &algorithm) < 0) { - sc_error(card->ctx, "CardOS does not support keys " + sc_debug(card->ctx, "CardOS does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } if (sc_profile_get_file(profile, "tempfile", &temp) < 0) { - sc_error(card->ctx, "Profile doesn't define temporary file " + sc_debug(card->ctx, "Profile doesn't define temporary file " "for key generation."); return SC_ERROR_NOT_SUPPORTED; } @@ -399,7 +399,7 @@ cardos_store_pin(sc_profile_t *profile, sc_card_t *card, * "no padding required". */ maxlen = MIN(profile->pin_maxlen, sizeof(pinpadded)); if (pin_len > maxlen) { - sc_error(card->ctx, "invalid pin length: %u (max %u)\n", + sc_debug(card->ctx, "invalid pin length: %u (max %u)\n", pin_len, maxlen); return SC_ERROR_INVALID_ARGUMENTS; } @@ -675,13 +675,13 @@ static int parse_ext_pubkey_file(sc_card_t *card, const u8 *data, size_t len, return SC_ERROR_INVALID_ARGUMENTS; data = sc_asn1_find_tag(card->ctx, data, len, 0x7f49, &ilen); if (data == NULL) { - sc_error(card->ctx, "invalid public key data: missing tag"); + sc_debug(card->ctx, "invalid public key data: missing tag"); return SC_ERROR_INTERNAL; } p = sc_asn1_find_tag(card->ctx, data, ilen, 0x81, &tlen); if (p == NULL) { - sc_error(card->ctx, "invalid public key data: missing modulus"); + sc_debug(card->ctx, "invalid public key data: missing modulus"); return SC_ERROR_INTERNAL; } pubkey->u.rsa.modulus.len = tlen; @@ -692,7 +692,7 @@ static int parse_ext_pubkey_file(sc_card_t *card, const u8 *data, size_t len, p = sc_asn1_find_tag(card->ctx, data, ilen, 0x82, &tlen); if (p == NULL) { - sc_error(card->ctx, "invalid public key data: missing exponent"); + sc_debug(card->ctx, "invalid public key data: missing exponent"); return SC_ERROR_INTERNAL; } pubkey->u.rsa.exponent.len = tlen; diff --git a/src/pkcs15init/pkcs15-cflex.c b/src/pkcs15init/pkcs15-cflex.c index 2c034906..172eacdb 100644 --- a/src/pkcs15init/pkcs15-cflex.c +++ b/src/pkcs15init/pkcs15-cflex.c @@ -72,9 +72,7 @@ cflex_delete_file(sc_profile_t *profile, sc_card_t *card, sc_file_t *df) path.value[1] = df->id & 0xFF; path.len = 2; - sc_ctx_suppress_errors_on(card->ctx); r = sc_delete_file(card, &path); - sc_ctx_suppress_errors_off(card->ctx); return r; } @@ -259,7 +257,7 @@ cflex_create_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_object_t *obj int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "Cryptoflex supports only RSA keys."); + sc_debug(card->ctx, "Cryptoflex supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } @@ -275,7 +273,7 @@ cflex_create_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_object_t *obj case 1024: size = 326; break; case 2048: size = 646; break; default: - sc_error(card->ctx, "Unsupported key size %u\n", + sc_debug(card->ctx, "Unsupported key size %u\n", key_info->modulus_length); r = SC_ERROR_INVALID_ARGUMENTS; goto out; @@ -316,7 +314,7 @@ cflex_generate_key(sc_profile_t *profile, sc_card_t *card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "Cryptoflex supports only RSA keys."); + sc_debug(card->ctx, "Cryptoflex supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } @@ -378,7 +376,7 @@ cflex_store_key(sc_profile_t *profile, sc_card_t *card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "Cryptoflex supports only RSA keys."); + sc_debug(card->ctx, "Cryptoflex supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } @@ -451,9 +449,7 @@ cflex_create_dummy_chvs(sc_profile_t *profile, sc_card_t *card, && !memcmp(ef.value, parent.value, ef.len)) continue; - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &ef, NULL); - sc_ctx_suppress_errors_off(card->ctx); } /* If a valid EF(CHVx) was found, we're fine */ @@ -524,9 +520,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_card_t *card, path.value[path.len++] = 0; /* See if the CHV already exists */ - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r >= 0) return SC_ERROR_FILE_ALREADY_EXISTS; @@ -534,7 +528,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_card_t *card, if (sc_profile_get_file_by_path(profile, &path, &file) < 0 && sc_profile_get_file(profile, (ref == 1)? "CHV1" : "CHV2", &file) < 0 && sc_profile_get_file(profile, "CHV", &file) < 0) { - sc_error(card->ctx, "profile does not define pin file ACLs\n"); + sc_debug(card->ctx, "profile does not define pin file ACLs\n"); return SC_ERROR_FILE_NOT_FOUND; } @@ -559,7 +553,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_card_t *card, file, SC_AC_OP_UPDATE, dummies); if (ndummies < 0) { - sc_error(card->ctx, + sc_debug(card->ctx, "Unable to create dummy CHV file: %s", sc_strerror(ndummies)); return ndummies; @@ -619,7 +613,7 @@ static int cflex_get_keyfiles(sc_profile_t *profile, sc_card_t *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_error(card->ctx, "Cannot find private key file info " + sc_debug(card->ctx, "Cannot find private key file info " "in profile (path=%s).", pbuf); return r; } @@ -629,7 +623,7 @@ static int cflex_get_keyfiles(sc_profile_t *profile, sc_card_t *card, sc_append_file_id(&path, 0x1012); r = sc_profile_get_file_by_path(profile, &path, pukf); if (r < 0) { - sc_error(card->ctx, "Cannot find public key file info in profile."); + sc_debug(card->ctx, "Cannot find public key file info in profile."); sc_file_free(*prkf); return r; } diff --git a/src/pkcs15init/pkcs15-entersafe.c b/src/pkcs15init/pkcs15-entersafe.c index b95b7c3b..070e7c8d 100644 --- a/src/pkcs15init/pkcs15-entersafe.c +++ b/src/pkcs15init/pkcs15-entersafe.c @@ -207,7 +207,7 @@ static int entersafe_create_dir(sc_profile_t *profile, sc_card_t *card, for(i = 0; create_efs[i]; ++i) { if (sc_profile_get_file(profile, create_efs[i], &file)) { - sc_error(card->ctx, "Inconsistent profile: cannot find %s", create_efs[i]); + sc_debug(card->ctx, "Inconsistent profile: cannot find %s", create_efs[i]); SC_FUNC_RETURN(card->ctx,4,SC_ERROR_INCONSISTENT_PROFILE); } diff --git a/src/pkcs15init/pkcs15-gpk.c b/src/pkcs15init/pkcs15-gpk.c index 2cc6c5d6..a8c7749d 100644 --- a/src/pkcs15init/pkcs15-gpk.c +++ b/src/pkcs15init/pkcs15-gpk.c @@ -103,7 +103,7 @@ gpk_erase_card(struct sc_profile *pro, sc_card_t *card) if (sc_card_ctl(card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0 && locked) { - sc_error(card->ctx, + sc_debug(card->ctx, "This card is already personalized, unable to " "create PKCS#15 structure."); return SC_ERROR_NOT_SUPPORTED; @@ -123,7 +123,7 @@ gpk_create_dir(sc_profile_t *profile, sc_card_t *card, sc_file_t *df) if (sc_card_ctl(card, SC_CARDCTL_GPK_IS_LOCKED, &locked) == 0 && locked) { - sc_error(card->ctx, + sc_debug(card->ctx, "This card is already personalized, unable to " "create PKCS#15 structure."); return SC_ERROR_NOT_SUPPORTED; @@ -327,7 +327,7 @@ gpk_init_pinfile(struct sc_profile *profile, sc_card_t *card, /* Create the PIN file. */ acl = sc_file_get_acl_entry(pinfile, SC_AC_OP_WRITE); if (acl->method != SC_AC_NEVER) { - sc_error(card->ctx, + sc_debug(card->ctx, "PIN file most be protected by WRITE=NEVER"); sc_file_free(pinfile); return SC_ERROR_INVALID_ARGUMENTS; @@ -423,7 +423,7 @@ gpk_create_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_object_t *obj) case SC_PKCS15_TYPE_PRKEY_DSA: algo = SC_ALGORITHM_DSA; break; default: - sc_error(card->ctx, "Unsupported public key algorithm"); + sc_debug(card->ctx, "Unsupported public key algorithm"); return SC_ERROR_NOT_SUPPORTED; } @@ -519,7 +519,7 @@ gpk_generate_key(sc_profile_t *profile, sc_card_t *card, } if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "GPK supports generating only RSA keys."); + sc_debug(card->ctx, "GPK supports generating only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } @@ -579,9 +579,7 @@ gpk_pkfile_create(sc_profile_t *profile, sc_card_t *card, sc_file_t *file) struct sc_file *found = NULL; int r; - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &file->path, &found); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_ERROR_FILE_NOT_FOUND) { r = sc_pkcs15init_create_file(profile, card, file); if (r >= 0) @@ -657,7 +655,7 @@ gpk_pkfile_init_public(sc_profile_t *profile, sc_card_t *card, sc_file_t *file, if (usage & (SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_NONREPUDIATION)) sysrec[2] &= ~0x20; if (sysrec[2] == 0x30) { - sc_error(card->ctx, "Key usage should specify at least one of sign or decipher"); + sc_debug(card->ctx, "Key usage should specify at least one of sign or decipher"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -682,14 +680,14 @@ gpk_pkfile_init_public(sc_profile_t *profile, sc_card_t *card, sc_file_t *file, || acl->method == SC_AC_NEVER) continue; if (acl->method != SC_AC_CHV) { - sc_error(card->ctx, + sc_debug(card->ctx, "Authentication method not " "supported for private key files.\n"); r = SC_ERROR_NOT_SUPPORTED; goto out; } if (++npins >= 2) { - sc_error(card->ctx, + sc_debug(card->ctx, "Too many pins for PrKEY file!\n"); r = SC_ERROR_NOT_SUPPORTED; goto out; @@ -711,13 +709,11 @@ gpk_pkfile_init_public(sc_profile_t *profile, sc_card_t *card, sc_file_t *file, for (n = 0; n < 6; n++) sysrec[6] ^= sysrec[n]; - sc_ctx_suppress_errors_on(card->ctx); r = sc_read_record(card, 1, buffer, sizeof(buffer), SC_RECORD_BY_REC_NR); - sc_ctx_suppress_errors_off(card->ctx); if (r >= 0) { if (r != 7 || buffer[0] != 0) { - sc_error(card->ctx, + sc_debug(card->ctx, "first record of public key file is not Lsys0"); return SC_ERROR_OBJECT_NOT_VALID; } @@ -747,10 +743,8 @@ gpk_pkfile_update_public(struct sc_profile *profile, /* If we've been given a key with public parts, write them now */ for (n = 2; n < 256; n++) { - sc_ctx_suppress_errors_on(card->ctx); r = sc_read_record(card, n, buffer, sizeof(buffer), SC_RECORD_BY_REC_NR); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) { r = 0; break; @@ -758,7 +752,7 @@ gpk_pkfile_update_public(struct sc_profile *profile, /* Check for bad record */ if (r < 2) { - sc_error(card->ctx, + sc_debug(card->ctx, "key file format error: " "record %u too small (%u bytes)\n", n, r); @@ -941,7 +935,7 @@ static int gpk_encode_rsa_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_prkey_info_t *info) { if (!rsa->modulus.len || !rsa->exponent.len) { - sc_error(card->ctx, + sc_debug(card->ctx, "incomplete RSA public key"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -950,7 +944,7 @@ static int gpk_encode_rsa_key(sc_profile_t *profile, sc_card_t *card, * the only exponent supported by GPK4000 and GPK8000 */ if (rsa->exponent.len != 3 || memcmp(rsa->exponent.data, "\001\000\001", 3)) { - sc_error(card->ctx, + sc_debug(card->ctx, "unsupported RSA exponent"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -969,7 +963,7 @@ static int gpk_encode_rsa_key(sc_profile_t *profile, sc_card_t *card, if (!rsa->p.len || !rsa->q.len || !rsa->dmp1.len || !rsa->dmq1.len || !rsa->iqmp.len) { /* No or incomplete CRT information */ if (!rsa->d.len) { - sc_error(card->ctx, + sc_debug(card->ctx, "incomplete RSA private key"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1019,7 +1013,7 @@ static int gpk_encode_dsa_key(sc_profile_t *profile, sc_card_t *card, { if (!dsa->p.len || !dsa->q.len || !dsa->g.len || !dsa->pub.len || !dsa->priv.len) { - sc_error(card->ctx, + sc_debug(card->ctx, "incomplete DSA public key"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1038,7 +1032,7 @@ static int gpk_encode_dsa_key(sc_profile_t *profile, sc_card_t *card, p->bits = 1024; p->bytes = 128; } else { - sc_error(card->ctx, + sc_debug(card->ctx, "incompatible DSA key size (%u bits)", p->bits); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1112,10 +1106,8 @@ gpk_read_rsa_key(sc_card_t *card, struct sc_pkcs15_pubkey_rsa *rsa) u8 buffer[256]; size_t m; - sc_ctx_suppress_errors_on(card->ctx); r = sc_read_record(card, n, buffer, sizeof(buffer), SC_RECORD_BY_REC_NR); - sc_ctx_suppress_errors_off(card->ctx); if (r < 1) break; diff --git a/src/pkcs15init/pkcs15-incrypto34.c b/src/pkcs15init/pkcs15-incrypto34.c index a6ef764e..f986e1b7 100644 --- a/src/pkcs15init/pkcs15-incrypto34.c +++ b/src/pkcs15init/pkcs15-incrypto34.c @@ -277,12 +277,12 @@ incrypto34_store_key(sc_profile_t *profile, sc_card_t *card, int algorithm, r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "Incrypto34 supports RSA keys only."); + sc_debug(card->ctx, "Incrypto34 supports RSA keys only."); return SC_ERROR_NOT_SUPPORTED; } if (incrypto34_key_algorithm(key_info->usage, &algorithm) < 0) { - sc_error(card->ctx, "Incrypto34 does not support keys " + sc_debug(card->ctx, "Incrypto34 does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } @@ -309,25 +309,25 @@ incrypto34_generate_key(sc_profile_t *profile, sc_card_t *card, int algorithm, r, delete_it = 0; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "Incrypto34 supports only RSA keys."); + sc_debug(card->ctx, "Incrypto34 supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } if (incrypto34_key_algorithm(key_info->usage, &algorithm) < 0) { - sc_error(card->ctx, "Incrypto34 does not support keys " + sc_debug(card->ctx, "Incrypto34 does not support keys " "that can both sign _and_ decrypt."); return SC_ERROR_NOT_SUPPORTED; } keybits = key_info->modulus_length & ~7UL; if (keybits > RSAKEY_MAX_BITS) { - sc_error(card->ctx, "Unable to generate key, max size is %d", + sc_debug(card->ctx, "Unable to generate key, max size is %d", RSAKEY_MAX_BITS); return SC_ERROR_INVALID_ARGUMENTS; } if (sc_profile_get_file(profile, "tempfile", &temp) < 0) { - sc_error(card->ctx, "Profile doesn't define temporary file " + sc_debug(card->ctx, "Profile doesn't define temporary file " "for key generation."); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/pkcs15init/pkcs15-jcop.c b/src/pkcs15init/pkcs15-jcop.c index a9268d54..e1af2542 100644 --- a/src/pkcs15init/pkcs15-jcop.c +++ b/src/pkcs15init/pkcs15-jcop.c @@ -148,7 +148,7 @@ jcop_create_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_object_t *obj int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "JCOP supports only RSA keys."); + sc_debug(card->ctx, "JCOP supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } /* The caller is supposed to have chosen a key file path for us */ @@ -225,7 +225,7 @@ jcop_store_key(sc_profile_t *profile, sc_card_t *card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "JCOP supports only RSA keys."); + sc_debug(card->ctx, "JCOP supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } r = sc_profile_get_file_by_path(profile, &key_info->path, &keyfile); @@ -261,7 +261,7 @@ jcop_generate_key(sc_profile_t *profile, sc_card_t *card, int r,delete_ok=0; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "JCOP supports only RSA keys."); + sc_debug(card->ctx, "JCOP supports only RSA keys."); return SC_ERROR_NOT_SUPPORTED; } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 6bc05473..8322a631 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -256,7 +256,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, return NULL; handle = lt_dlopen(libname); if (handle == NULL) { - sc_error(ctx, "Module %s: cannot load '%s' library: %s\n", name, libname, lt_dlerror()); + sc_debug(ctx, "Module %s: cannot load '%s' library: %s\n", name, libname, lt_dlerror()); return NULL; } @@ -264,14 +264,14 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, modinit = (void *(*)(const char *)) lt_dlsym(handle, "sc_module_init"); modversion = (const char *(*)(void)) lt_dlsym(handle, "sc_driver_version"); if (modinit == NULL || modversion == NULL) { - sc_error(ctx, "dynamic library '%s' is not a OpenSC module\n",libname); + sc_debug(ctx, "dynamic library '%s' is not a OpenSC module\n",libname); lt_dlclose(handle); return NULL; } /* verify module version */ version = modversion(); if (version == NULL || strncmp(version, "0.9.", strlen("0.9.")) > 0) { - sc_error(ctx,"dynamic library '%s': invalid module version\n",libname); + sc_debug(ctx,"dynamic library '%s': invalid module version\n",libname); lt_dlclose(handle); return NULL; } @@ -318,7 +318,7 @@ sc_pkcs15init_bind(sc_card_t *card, const char *name, if (func) { profile->ops = func(); } else { - sc_error(card->ctx, "Unsupported card driver %s", driver); + sc_debug(card->ctx, "Unsupported card driver %s", driver); sc_profile_free(profile); return SC_ERROR_NOT_SUPPORTED; } @@ -355,7 +355,7 @@ sc_pkcs15init_bind(sc_card_t *card, const char *name, if ((r = sc_profile_load(profile, profile->name)) < 0 || (r = sc_profile_load(profile, card_profile)) < 0 || (r = sc_profile_finish(profile)) < 0) { - sc_error(card->ctx, "Failed to load profile: %s\n", sc_strerror(r)); + sc_debug(card->ctx, "Failed to load profile: %s\n", sc_strerror(r)); sc_profile_free(profile); return r; } @@ -373,7 +373,7 @@ sc_pkcs15init_unbind(struct sc_profile *profile) if (profile->dirty != 0 && profile->p15_data != NULL && profile->pkcs15.do_last_update) { r = sc_pkcs15init_update_tokeninfo(profile->p15_data, profile); if (r < 0) - sc_error(ctx, "Failed to update TokenInfo: %s\n", sc_strerror(r)); + sc_debug(ctx, "Failed to update TokenInfo: %s\n", sc_strerror(r)); } if (profile->dll) lt_dlclose(profile->dll); @@ -406,13 +406,11 @@ sc_pkcs15init_erase_card(sc_card_t *card, struct sc_profile *profile) if (sc_keycache_find_named_pin(NULL, SC_PKCS15INIT_SO_PIN) == -1) { struct sc_pkcs15_card *p15card = NULL; - sc_ctx_suppress_errors_on(card->ctx); if (sc_pkcs15_bind(card, &p15card) >= 0) { /* result of set_so_pin_from_card ignored */ set_so_pin_from_card(p15card, profile); profile->p15_data = p15card; } - sc_ctx_suppress_errors_off(card->ctx); } if (profile->ops->erase_card == NULL) return SC_ERROR_NOT_SUPPORTED; @@ -432,13 +430,11 @@ sc_pkcs15init_erase_card_recursively(sc_card_t *card, if (sc_keycache_find_named_pin(NULL, SC_PKCS15INIT_SO_PIN) == -1) { struct sc_pkcs15_card *p15card = NULL; - sc_ctx_suppress_errors_on(card->ctx); if (sc_pkcs15_bind(card, &p15card) >= 0) { /* result of set_so_pin_from_card ignored */ set_so_pin_from_card(p15card, profile); profile->p15_data = p15card; } - sc_ctx_suppress_errors_off(card->ctx); } /* Delete EF(DIR). This may not be very nice @@ -455,9 +451,7 @@ sc_pkcs15init_erase_card_recursively(sc_card_t *card, goto out; } - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &df->path, &df); - sc_ctx_suppress_errors_off(card->ctx); if (r >= 0) { r = sc_pkcs15init_rmdir(card, profile, df); sc_file_free(df); @@ -546,9 +540,7 @@ sc_pkcs15init_rmdir(sc_card_t *card, struct sc_profile *profile, SC_AC_OP_LIST_FILES); if (r < 0) return r; - sc_ctx_suppress_errors_on(card->ctx); r = sc_list_files(card, buffer, sizeof(buffer)); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) return r; @@ -601,9 +593,7 @@ sc_pkcs15init_rmdir(sc_card_t *card, struct sc_profile *profile, if (r < 0 && r != SC_ERROR_NOT_SUPPORTED) return r; - sc_ctx_suppress_errors_on(card->ctx); r = sc_delete_file(card, &path); - sc_ctx_suppress_errors_off(card->ctx); return r; } @@ -635,7 +625,7 @@ sc_pkcs15init_add_app(sc_card_t *card, struct sc_profile *profile, sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &puk_info); if (card->app_count >= SC_MAX_CARD_APPS) { - sc_error(card->ctx, "Too many applications on this card."); + sc_debug(card->ctx, "Too many applications on this card."); return SC_ERROR_TOO_MANY_OBJECTS; } @@ -788,9 +778,7 @@ sc_pkcs15init_add_app(sc_card_t *card, struct sc_profile *profile, free(app); /* unused */ } - sc_ctx_suppress_errors_on(card->ctx); sc_pkcs15init_write_info(card, profile, pin_obj); - sc_ctx_suppress_errors_off(card->ctx); return r; } @@ -977,7 +965,6 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, unsigned int n; args->auth_id.len = 1; - sc_ctx_suppress_errors_on(card->ctx); for (n = 1, r = 0; n < 256; n++) { args->auth_id.value[0] = n; r = sc_pkcs15_find_pin_by_auth_id(p15card, @@ -985,20 +972,17 @@ sc_pkcs15init_store_pin(struct sc_pkcs15_card *p15card, if (r == SC_ERROR_OBJECT_NOT_FOUND) break; } - sc_ctx_suppress_errors_off(card->ctx); if (r != SC_ERROR_OBJECT_NOT_FOUND) { - sc_error(card->ctx, "No auth_id specified for new PIN"); + sc_debug(card->ctx, "No auth_id specified for new PIN"); return SC_ERROR_INVALID_ARGUMENTS; } } else { struct sc_pkcs15_object *dummy; /* Make sure we don't get duplicate PIN IDs */ - sc_ctx_suppress_errors_on(card->ctx); r = sc_pkcs15_find_pin_by_auth_id(p15card, &args->auth_id, &dummy); - sc_ctx_suppress_errors_off(card->ctx); if (r != SC_ERROR_OBJECT_NOT_FOUND) { - sc_error(card->ctx, "There already is a PIN with this ID."); + sc_debug(card->ctx, "There already is a PIN with this ID."); return SC_ERROR_INVALID_ARGUMENTS; } } @@ -1065,7 +1049,7 @@ sc_pkcs15init_create_pin(sc_pkcs15_card_t *p15card, sc_profile_t *profile, */ if (profile->pin_domains) { if (!profile->ops->create_domain) { - sc_error(card->ctx, "PIN domains not supported."); + sc_debug(card->ctx, "PIN domains not supported."); return SC_ERROR_NOT_SUPPORTED; } r = profile->ops->create_domain(profile, card, @@ -1096,7 +1080,7 @@ sc_pkcs15init_create_pin(sc_pkcs15_card_t *p15card, sc_profile_t *profile, if (r != 0 || !retry) { /* Other error trying to retrieve pin obj */ - sc_error(card->ctx, "Failed to allocate PIN reference."); + sc_debug(card->ctx, "Failed to allocate PIN reference."); return SC_ERROR_TOO_MANY_OBJECTS; } @@ -1277,7 +1261,7 @@ sc_pkcs15init_init_prkdf(sc_pkcs15_card_t *p15card, if (r != 0) { /* Other error trying to retrieve pin obj */ - sc_error(card->ctx, + sc_debug(card->ctx, "Failed to select key reference."); return SC_ERROR_TOO_MANY_OBJECTS; } @@ -1419,12 +1403,12 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, /* Make sure the caller explicitly tells us to store * the key non-natively. */ if (!(keyargs->flags & SC_PKCS15INIT_EXTRACTABLE)) { - sc_error(card->ctx, "Card does not support this key."); + sc_debug(card->ctx, "Card does not support this key."); return SC_ERROR_INCOMPATIBLE_KEY; } if (!keyargs->passphrase && !(keyargs->flags & SC_PKCS15INIT_NO_PASSPHRASE)) { - sc_error(card->ctx, + sc_debug(card->ctx, "No key encryption passphrase given."); return SC_ERROR_PASSPHRASE_REQUIRED; } @@ -1610,7 +1594,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, type = SC_PKCS15_TYPE_PUBKEY_DSA; break; #endif default: - sc_error(p15card->card->ctx, "Unsupported key algorithm.\n"); + sc_debug(p15card->card->ctx, "Unsupported key algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -1726,7 +1710,7 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card, && sc_pkcs15_find_prkey_by_id(p15card, &args->id, &object) == 0) { r = set_user_pin_from_authid(p15card, profile, &object->auth_id); if (r < 0) { - sc_error(p15card->card->ctx, + sc_debug(p15card->card->ctx, "Failed to assign user pin reference " "(copied from private key auth_id)\n"); return r; @@ -1898,7 +1882,7 @@ sc_pkcs15init_store_data(struct sc_pkcs15_card *p15card, r = profile->ops->new_file(profile, p15card->card, object->type, idx, &file); if (r < 0) { - sc_error(p15card->card->ctx, "Unable to allocate file"); + sc_debug(p15card->card->ctx, "Unable to allocate file"); goto done; } } @@ -2071,7 +2055,7 @@ check_key_compatibility(struct sc_pkcs15_card *p15card, res = __check_key_compatibility(p15card, key, x509_usage, key_length, flags); if (res < 0) { - sc_error(p15card->card->ctx, + sc_debug(p15card->card->ctx, "This device requires that keys have a " "specific key usage.\n" "Keys can be used for either signature or decryption, " @@ -2107,7 +2091,7 @@ prkey_fixup_rsa(sc_pkcs15_card_t *p15card, struct sc_pkcs15_prkey_rsa *key) { if (!key->modulus.len || !key->exponent.len || !key->d.len || !key->p.len || !key->q.len) { - sc_error(p15card->card->ctx, + sc_debug(p15card->card->ctx, "Missing private RSA coefficient"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -2192,7 +2176,7 @@ prkey_bits(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_t *key) case SC_ALGORITHM_DSA: return sc_pkcs15init_keybits(&key->u.dsa.q); } - sc_error(p15card->card->ctx, "Unsupported key algorithm.\n"); + sc_debug(p15card->card->ctx, "Unsupported key algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -2205,7 +2189,7 @@ prkey_pkcs15_algo(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_t *key) case SC_ALGORITHM_DSA: return SC_PKCS15_TYPE_PRKEY_DSA; } - sc_error(p15card->card->ctx, "Unsupported key algorithm.\n"); + sc_debug(p15card->card->ctx, "Unsupported key algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; } @@ -2386,9 +2370,7 @@ sc_pkcs15init_update_dir(struct sc_pkcs15_card *p15card, struct sc_file *dir_file; struct sc_path path; - sc_ctx_suppress_errors_on(card->ctx); r = sc_enum_apps(card); - sc_ctx_suppress_errors_off(card->ctx); if (r != SC_ERROR_FILE_NOT_FOUND) break; @@ -2425,19 +2407,19 @@ static char *get_generalized_time(sc_context_t *ctx) #endif tm_time = gmtime(&t); if (tm_time == NULL) { - sc_error(ctx, "error: gmtime failed\n"); + sc_debug(ctx, "error: gmtime failed\n"); return NULL; } ret = calloc(1, 16); if (ret == NULL) { - sc_error(ctx, "error: calloc failed\n"); + sc_debug(ctx, "error: calloc failed\n"); return NULL; } /* print time in generalized time format */ r = strftime(ret, 16, "%Y%m%d%H%M%SZ", tm_time); if (r == 0) { - sc_error(ctx, "error: strftime failed\n"); + sc_debug(ctx, "error: strftime failed\n"); free(ret); return NULL; } @@ -2584,7 +2566,7 @@ sc_pkcs15init_add_object(struct sc_pkcs15_card *p15card, } else { file = profile->df[df_type]; if (file == NULL) { - sc_error(card->ctx, + sc_debug(card->ctx, "Profile doesn't define a DF file %u", df_type); return SC_ERROR_NOT_SUPPORTED; @@ -2849,7 +2831,7 @@ int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card, if (stored_in_ef != 0) { r = sc_pkcs15init_delete_by_path(profile, p15card->card, &path); if (r != SC_SUCCESS) { - sc_error(p15card->card->ctx, "sc_pkcs15init_delete_by_path failed: %d", r); + sc_debug(p15card->card->ctx, "sc_pkcs15init_delete_by_path failed: %d", r); return r; } /* Get the DF we're part of. If there's no DF, fine, we haven't @@ -2865,7 +2847,7 @@ int sc_pkcs15init_delete_object(sc_pkcs15_card_t *p15card, * object in the future. */ r = profile->ops->delete_object(profile, p15card->card, obj->type, obj->data, &path); if (r < 0) { - sc_error(p15card->card->ctx, "ops->delete_object() failed: %d", r); + sc_debug(p15card->card->ctx, "ops->delete_object() failed: %d", r); return r; } @@ -3112,7 +3094,7 @@ found: if (type == SC_AC_CHV && pin_info.flags & SC_PKCS15_PIN_FLAG_NEEDS_PADDIN r = sc_select_file(card, &file->path, NULL); if (r >= 0 && (r = sc_verify(card, type, reference, pinbuf, *pinsize, NULL)) < 0) { - sc_error(card->ctx, "Failed to verify %s (ref=0x%x)", + sc_debug(card->ctx, "Failed to verify %s (ref=0x%x)", ident, reference); } } @@ -3323,9 +3305,7 @@ static int do_select_parent(struct sc_profile *pro, sc_card_t *card, /* Select the parent DF. */ *parent = NULL; - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &path, parent); - sc_ctx_suppress_errors_off(card->ctx); /* If DF doesn't exist, create it (unless it's the MF, * but then something's badly broken anyway :-) */ if (r == SC_ERROR_FILE_NOT_FOUND && path.len != 2) { @@ -3337,7 +3317,7 @@ static int do_select_parent(struct sc_profile *pro, sc_card_t *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_error(card->ctx, + sc_debug(card->ctx, "profile doesn't define a DF %s", pbuf); return r; } @@ -3355,7 +3335,7 @@ static int do_select_parent(struct sc_profile *pro, sc_card_t *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_error(card->ctx, + sc_debug(card->ctx, "profile doesn't define a DF %s", pbuf); return r; } @@ -3406,9 +3386,7 @@ sc_pkcs15init_update_file(struct sc_profile *profile, sc_card_t *card, pbuf[0] = '\0'; sc_debug(card->ctx, "called, path=%s, %u bytes\n", pbuf, datalen); - sc_ctx_suppress_errors_on(card->ctx); if ((r = sc_select_file(card, &file->path, &info)) < 0) { - sc_ctx_suppress_errors_off(card->ctx); /* Create file if it doesn't exist */ if (file->size < datalen) file->size = datalen; @@ -3417,7 +3395,6 @@ sc_pkcs15init_update_file(struct sc_profile *profile, sc_card_t *card, || (r = sc_select_file(card, &file->path, &info)) < 0) return r; } else { - sc_ctx_suppress_errors_off(card->ctx); need_to_zap = 1; } @@ -3426,7 +3403,7 @@ sc_pkcs15init_update_file(struct sc_profile *profile, sc_card_t *card, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_error(card->ctx, + sc_debug(card->ctx, "File %s too small (require %u, have %u) - " "please increase size in profile", pbuf, datalen, info->size); @@ -3552,7 +3529,7 @@ sc_pkcs15init_fixup_acls(struct sc_profile *profile, sc_file_t *file, acl = user_acl; what = "user PIN"; } else { - sc_error(card->ctx, + sc_debug(card->ctx, "ACL references unknown symbolic PIN %d", acl->key_ref); return SC_ERROR_INVALID_ARGUMENTS; @@ -3561,7 +3538,7 @@ sc_pkcs15init_fixup_acls(struct sc_profile *profile, sc_file_t *file, /* If we weren't given a replacement ACL, * leave the original ACL untouched */ if (acl == NULL || acl->key_ref == (unsigned int)-1) { - sc_error(card->ctx, + sc_debug(card->ctx, "ACL references %s, which is not defined", what); return SC_ERROR_INVALID_ARGUMENTS; @@ -3646,12 +3623,12 @@ static int sc_pkcs15init_qualify_pin(sc_card_t *card, const char *pin_name, if (pin_len == 0) return 0; if (pin_len < pin_info->min_length) { - sc_error(card->ctx, "%s too short (min length %u)", + sc_debug(card->ctx, "%s too short (min length %u)", pin_name, pin_info->min_length); return SC_ERROR_WRONG_LENGTH; } if (pin_len > pin_info->max_length) { - sc_error(card->ctx, "%s too long (max length %u)", + sc_debug(card->ctx, "%s too long (max length %u)", pin_name, pin_info->max_length); return SC_ERROR_WRONG_LENGTH; } @@ -3671,7 +3648,6 @@ sc_pkcs15init_read_info(sc_card_t *card, sc_profile_t *profile) size_t len = 0; int r; - sc_ctx_suppress_errors_on(card->ctx); sc_format_path(OPENSC_INFO_FILEPATH, &path); if ((r = sc_select_file(card, &path, &file)) >= 0) { len = file->size; @@ -3683,7 +3659,6 @@ sc_pkcs15init_read_info(sc_card_t *card, sc_profile_t *profile) } else { r = 0; } - sc_ctx_suppress_errors_off(card->ctx); if (r >= 0) r = sc_pkcs15init_parse_info(card, mem, len, profile); @@ -3751,7 +3726,7 @@ sc_pkcs15init_parse_info(sc_card_t *card, break; case OPENSC_INFO_TAG_OPTION: if (nopts >= SC_PKCS15INIT_MAX_OPTIONS - 1) { - sc_error(card->ctx, + sc_debug(card->ctx, "Too many options in OpenSC Info file\n"); return SC_ERROR_PKCS15INIT; } @@ -3768,7 +3743,7 @@ sc_pkcs15init_parse_info(sc_card_t *card, return 0; error: - sc_error(card->ctx, "OpenSC info file corrupted\n"); + sc_debug(card->ctx, "OpenSC info file corrupted\n"); return SC_ERROR_PKCS15INIT; } diff --git a/src/pkcs15init/pkcs15-miocos.c b/src/pkcs15init/pkcs15-miocos.c index 8fd3c0f1..ae25250e 100644 --- a/src/pkcs15init/pkcs15-miocos.c +++ b/src/pkcs15init/pkcs15-miocos.c @@ -122,7 +122,7 @@ miocos_new_file(struct sc_profile *profile, sc_card_t *card, * the generic class (SC_PKCS15_TYPE_CERT) */ if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) { - sc_error(card->ctx, + sc_debug(card->ctx, "File type not supported by card driver"); return SC_ERROR_INVALID_ARGUMENTS; } @@ -131,7 +131,7 @@ miocos_new_file(struct sc_profile *profile, sc_card_t *card, snprintf(name, sizeof(name), "template-%s", tag); if (sc_profile_get_file(profile, name, &file) < 0) { - sc_error(card->ctx, "Profile doesn't define %s template (%s)", + sc_debug(card->ctx, "Profile doesn't define %s template (%s)", desc, name); return SC_ERROR_NOT_SUPPORTED; } @@ -177,12 +177,12 @@ miocos_new_key(struct sc_profile *profile, sc_card_t *card, int r; if (key->algorithm != SC_ALGORITHM_RSA) { - sc_error(card->ctx, "MioCOS supports only 1024-bit RSA keys."); + sc_debug(card->ctx, "MioCOS supports only 1024-bit RSA keys."); return SC_ERROR_NOT_SUPPORTED; } rsa = &key->u.rsa; if (rsa->modulus.len != 128) { - sc_error(card->ctx, "MioCOS supports only 1024-bit RSA keys."); + sc_debug(card->ctx, "MioCOS supports only 1024-bit RSA keys."); return SC_ERROR_NOT_SUPPORTED; } r = miocos_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, diff --git a/src/pkcs15init/pkcs15-muscle.c b/src/pkcs15init/pkcs15-muscle.c index b30cec89..9c518ae9 100644 --- a/src/pkcs15init/pkcs15-muscle.c +++ b/src/pkcs15init/pkcs15-muscle.c @@ -179,7 +179,7 @@ muscle_store_key(sc_profile_t *profile, sc_card_t *card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "Muscle supports RSA keys only."); + sc_debug(card->ctx, "Muscle supports RSA keys only."); return SC_ERROR_NOT_SUPPORTED; } /* Verification stuff */ @@ -217,7 +217,7 @@ muscle_store_key(sc_profile_t *profile, sc_card_t *card, r = sc_card_ctl(card, SC_CARDCTL_MUSCLE_IMPORT_KEY, &info); if (r < 0) { - sc_error(card->ctx, "Unable to import key"); + sc_debug(card->ctx, "Unable to import key"); SC_FUNC_RETURN(card->ctx, 2,r); } return r; @@ -236,12 +236,12 @@ muscle_generate_key(sc_profile_t *profile, sc_card_t *card, int r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - sc_error(card->ctx, "Muscle supports only RSA keys (for now)."); + sc_debug(card->ctx, "Muscle supports only RSA keys (for now)."); SC_FUNC_RETURN(card->ctx, 2,SC_ERROR_NOT_SUPPORTED); } keybits = key_info->modulus_length & ~7UL; if (keybits > 2048) { - sc_error(card->ctx, "Unable to generate key, max size is %d", + sc_debug(card->ctx, "Unable to generate key, max size is %d", 2048); SC_FUNC_RETURN(card->ctx, 2,SC_ERROR_INVALID_ARGUMENTS); } @@ -269,7 +269,7 @@ muscle_generate_key(sc_profile_t *profile, sc_card_t *card, r = sc_card_ctl(card, SC_CARDCTL_MUSCLE_GENERATE_KEY, &args); if (r < 0) { - sc_error(card->ctx, "Unable to generate key"); + sc_debug(card->ctx, "Unable to generate key"); SC_FUNC_RETURN(card->ctx, 2,r); } @@ -280,7 +280,7 @@ muscle_generate_key(sc_profile_t *profile, sc_card_t *card, extArgs.keyLocation = args.publicKeyLocation; r = sc_card_ctl(card, SC_CARDCTL_MUSCLE_EXTRACT_KEY, &extArgs); if (r < 0) { - sc_error(card->ctx, "Unable to extract the public key"); + sc_debug(card->ctx, "Unable to extract the public key"); SC_FUNC_RETURN(card->ctx, 2,r); } diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 2b0a32e9..6d85d7c9 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -133,7 +133,6 @@ static int cosm_erase_card(struct sc_profile *profile, sc_card_t *card) * Note we need to delete if before the DF because we create * it *after* the DF. * */ - sc_ctx_suppress_errors_on(card->ctx); if (sc_profile_get_file(profile, "DIR", &dir) >= 0) { sc_debug(card->ctx, "erase file dir %04X\n",dir->id); rv = cosm_delete_file(card, profile, dir); @@ -170,7 +169,6 @@ static int cosm_erase_card(struct sc_profile *profile, sc_card_t *card) done: sc_keycache_forget_key(NULL, -1, -1); - sc_ctx_suppress_errors_off(card->ctx); if (rv==SC_ERROR_FILE_NOT_FOUND) rv=0; @@ -217,7 +215,7 @@ cosm_init_app(struct sc_profile *profile, sc_card_t *card, /* Create private objects DF */ for (ii = 0; create_dfs[ii]; ii++) { if (sc_profile_get_file(profile, create_dfs[ii], &file)) { - sc_error(card->ctx, "Inconsistent profile: cannot find %s", create_dfs[ii]); + sc_debug(card->ctx, "Inconsistent profile: cannot find %s", create_dfs[ii]); return SC_ERROR_INCONSISTENT_PROFILE; } @@ -318,7 +316,7 @@ static int cosm_update_pin(struct sc_profile *profile, sc_card_t *card, sc_debug(card->ctx, "ref %i; flags %X\n", pinfo->reference, pinfo->flags); if (pinfo->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { - sc_error(card->ctx,"Pin references should be only in the profile" + sc_debug(card->ctx,"Pin references should be only in the profile" "and in the card-oberthur.\n"); if (pinfo->reference != 4) return SC_ERROR_INVALID_PIN_REFERENCE; @@ -327,7 +325,7 @@ static int cosm_update_pin(struct sc_profile *profile, sc_card_t *card, pin, pin_len, &tries_left); sc_debug(card->ctx, "return value %X; tries left %i\n", rv, tries_left); if (tries_left != -1) - sc_error(card->ctx, "Failed to change reference data for soPin: rv %X", rv); + sc_debug(card->ctx, "Failed to change reference data for soPin: rv %X", rv); } else { @@ -347,7 +345,7 @@ cosm_select_pin_reference(sc_profile_t *profile, sc_card_t *card, SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "ref %i; flags %X\n", pin_info->reference, pin_info->flags); if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0) { - sc_error(card->ctx, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF"); + sc_debug(card->ctx, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF"); return SC_ERROR_INCONSISTENT_PROFILE; } @@ -383,7 +381,7 @@ cosm_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df, SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "ref %i; flags %X\n", pinfo->reference, pinfo->flags); if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0) { - sc_error(card->ctx, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF"); + sc_debug(card->ctx, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF"); return SC_ERROR_INCONSISTENT_PROFILE; } @@ -469,7 +467,7 @@ cosm_new_file(struct sc_profile *profile, sc_card_t *card, * the generic class (SC_PKCS15_TYPE_CERT) */ if (!(type & ~SC_PKCS15_TYPE_CLASS_MASK)) { - sc_error(card->ctx, "File type %X not supported by card driver", + sc_debug(card->ctx, "File type %X not supported by card driver", type); return SC_ERROR_INVALID_ARGUMENTS; } @@ -478,7 +476,7 @@ cosm_new_file(struct sc_profile *profile, sc_card_t *card, sc_debug(card->ctx, "template %s; num %i\n",_template, num); if (sc_profile_get_file(profile, _template, &file) < 0) { - sc_error(card->ctx, "Profile doesn't define %s template '%s'\n", + sc_debug(card->ctx, "Profile doesn't define %s template '%s'\n", desc, _template); return SC_ERROR_NOT_SUPPORTED; } @@ -514,7 +512,7 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card, SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "index %i; nn %i\n", idx, keybits); if (keybits < 512 || keybits > 2048 || (keybits%0x20)) { - sc_error(card->ctx, "Unsupported key size %u\n", keybits); + sc_debug(card->ctx, "Unsupported key size %u\n", keybits); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1003,7 +1001,7 @@ cosm_update_df_new_object(struct sc_pkcs15_card *p15card, cosm_free_data_info(&idata); break; default: - sc_error(card->ctx, "Unsupported type %i\n", object->type); + sc_debug(card->ctx, "Unsupported type %i\n", object->type); return SC_ERROR_INVALID_ARGUMENTS; } @@ -1061,7 +1059,7 @@ cosm_update_tokeninfo (struct sc_pkcs15_card *p15card, SC_FUNC_CALLED(p15card->card->ctx, 1); if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) { - sc_error(p15card->card->ctx, + sc_debug(p15card->card->ctx, "Inconsistent profile: cannot find "COSM_TITLE"-token-info"); return SC_ERROR_INCONSISTENT_PROFILE; } diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index d49b019e..7172dae3 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -171,7 +171,7 @@ static int rtecp_create_pin(sc_profile_t *profile, sc_card_t *card, SC_FUNC_CALLED(card->ctx, 1); if (puk_len != 0) { - sc_error(card->ctx, "Do not enter User unblocking PIN (PUK): %s\n", + sc_debug(card->ctx, "Do not enter User unblocking PIN (PUK): %s\n", sc_strerror(SC_ERROR_NOT_SUPPORTED)); return SC_ERROR_NOT_SUPPORTED; } @@ -267,7 +267,7 @@ static int rtecp_create_key(sc_profile_t *profile, sc_card_t *card, assert(key_info); if (key_info->modulus_length % 128 != 0) { - sc_error(card->ctx, "Unsupported key size %u\n", + sc_debug(card->ctx, "Unsupported key size %u\n", key_info->modulus_length); return SC_ERROR_INVALID_ARGUMENTS; } diff --git a/src/pkcs15init/pkcs15-rutoken.c b/src/pkcs15init/pkcs15-rutoken.c index 280334a0..b60c1720 100644 --- a/src/pkcs15init/pkcs15-rutoken.c +++ b/src/pkcs15init/pkcs15-rutoken.c @@ -206,7 +206,7 @@ rutoken_create_pin(sc_profile_t *profile, sc_card_t *card, if (puk_len != 0) { - sc_error(card->ctx, "Do not enter User unblocking PIN (PUK): %s\n", + sc_debug(card->ctx, "Do not enter User unblocking PIN (PUK): %s\n", sc_strerror(SC_ERROR_NOT_SUPPORTED)); return SC_ERROR_NOT_SUPPORTED; } @@ -220,7 +220,7 @@ rutoken_create_pin(sc_profile_t *profile, sc_card_t *card, return SC_SUCCESS; else { - sc_error(card->ctx, "Incorrect PIN\n"); + sc_debug(card->ctx, "Incorrect PIN\n"); break; } } @@ -457,14 +457,14 @@ rutoken_erase(struct sc_profile *profile, sc_card_t *card) { ret = create_typical_fs(card); if (ret != SC_SUCCESS) - sc_error(card->ctx, "Failed to create typical fs: %s\n", + sc_debug(card->ctx, "Failed to create typical fs: %s\n", sc_strerror(ret)); ret_end = sc_card_ctl(card, SC_CARDCTL_RUTOKEN_FORMAT_END, NULL); if (ret_end != SC_SUCCESS) ret = ret_end; } if (ret != SC_SUCCESS) - sc_error(card->ctx, "Failed to erase: %s\n", sc_strerror(ret)); + sc_debug(card->ctx, "Failed to erase: %s\n", sc_strerror(ret)); else sc_free_apps(card); return ret; diff --git a/src/pkcs15init/pkcs15-setcos.c b/src/pkcs15init/pkcs15-setcos.c index f22f86ee..797932ba 100644 --- a/src/pkcs15init/pkcs15-setcos.c +++ b/src/pkcs15init/pkcs15-setcos.c @@ -97,9 +97,7 @@ setcos_init_card(sc_profile_t *profile, sc_card_t *card) pin_ref, SC_PKCS15INIT_SO_PIN); /* Create the MF if it doesn't exist yet */ - card->ctx->suppress_errors++; r = sc_select_file(card, &mf->path, NULL); - card->ctx->suppress_errors--; if (r == SC_ERROR_FILE_NOT_FOUND) { sc_debug(card->ctx, "MF doesn't exist, creating now"); @@ -115,9 +113,7 @@ setcos_init_card(sc_profile_t *profile, sc_card_t *card) r = sc_profile_get_file(profile, "pinfile", &pinfile); if (r < 0) return r; - card->ctx->suppress_errors++; r = sc_select_file(card, &pinfile->path, NULL); - card->ctx->suppress_errors--; if (r == SC_ERROR_FILE_NOT_FOUND) { sc_debug(card->ctx, "Global pin file doesn't exist, creating now"); @@ -169,9 +165,7 @@ static int setcos_init_app(sc_profile_t *profile, sc_card_t *card, pin_ref, SC_PKCS15INIT_SO_PIN); /* Create the MF if it doesn't exist yet */ - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &mf->path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_ERROR_FILE_NOT_FOUND) { sc_debug(card->ctx, "MF doesn't exist, creating now"); /* Fix up the file's ACLs */ @@ -188,9 +182,7 @@ static int setcos_init_app(sc_profile_t *profile, sc_card_t *card, /* Create the global pin file if it doesn't exist yet */ if ((r = sc_profile_get_file(profile, "pinfile", &pinfile)) < 0) goto done; - sc_ctx_suppress_errors_on(card->ctx); r = sc_select_file(card, &pinfile->path, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_ERROR_FILE_NOT_FOUND) { sc_debug(card->ctx, "Global pin file doesn't exist, creating now"); /* Fix up the file's ACLs */ @@ -299,14 +291,14 @@ setcos_new_file(sc_profile_t *profile, sc_card_t *card, else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT) tag = "data"; else { - sc_error(card->ctx, "Unsupported file type"); + sc_debug(card->ctx, "Unsupported file type"); return SC_ERROR_INVALID_ARGUMENTS; } /* Get template from profile */ snprintf(name, sizeof(name), "template-%s", tag); if (sc_profile_get_file(profile, name, &file) < 0) { - sc_error(card->ctx, "Profile doesn't define %s", name); + sc_debug(card->ctx, "Profile doesn't define %s", name); return SC_ERROR_NOT_SUPPORTED; } @@ -396,7 +388,7 @@ setcos_generate_store_key(sc_profile_t *profile, sc_card_t *card, /* Parameter check */ if ( (keybits < 512) || (keybits > 1024) || (keybits & 0X7)) { - sc_error(card->ctx, "Unsupported key size [%u]: 512-1024 bit + 8-multiple\n", keybits); + sc_debug(card->ctx, "Unsupported key size [%u]: 512-1024 bit + 8-multiple\n", keybits); return SC_ERROR_INVALID_ARGUMENTS; } @@ -465,7 +457,7 @@ setcos_generate_store_key(sc_profile_t *profile, sc_card_t *card, mod_len = ((raw_pubkey[0] * 256) + raw_pubkey[1]); /* modulus bit length */ if (mod_len != keybits){ - sc_error(card->ctx, "key-size from card[%i] does not match[%i]\n", mod_len, keybits); + sc_debug(card->ctx, "key-size from card[%i] does not match[%i]\n", mod_len, keybits); r = SC_ERROR_PKCS15INIT; goto done; } diff --git a/src/pkcs15init/pkcs15-starcos.c b/src/pkcs15init/pkcs15-starcos.c index 33a37e48..c3f57440 100644 --- a/src/pkcs15init/pkcs15-starcos.c +++ b/src/pkcs15init/pkcs15-starcos.c @@ -89,9 +89,7 @@ static int starcos_init_card(sc_profile_t *profile, sc_card_t *card) tpath.value[1] = 0x00; tpath.len = 2; tpath.type = SC_PATH_TYPE_PATH; - sc_ctx_suppress_errors_on(card->ctx); ret = sc_select_file(card, &tpath, NULL); - sc_ctx_suppress_errors_off(card->ctx); if (ret == SC_SUCCESS) /* we already have a MF => return OK */ return ret; @@ -899,17 +897,13 @@ static int starcos_finalize_card(sc_card_t *card) /* call CREATE END for the MF (ignore errors) */ tfile.type = SC_FILE_TYPE_DF; tfile.id = 0x3f00; - sc_ctx_suppress_errors_on(card->ctx); r = sc_card_ctl(card, SC_CARDCTL_STARCOS_CREATE_END, &tfile); - sc_ctx_suppress_errors_off(card->ctx); if (r < 0) sc_debug(card->ctx, "failed to call CREATE END for the MF\n"); /* call CREATE END for the apps (pkcs15) DF */ tfile.type = SC_FILE_TYPE_DF; tfile.id = 0x5015; - sc_ctx_suppress_errors_on(card->ctx); r = sc_card_ctl(card, SC_CARDCTL_STARCOS_CREATE_END, &tfile); - sc_ctx_suppress_errors_off(card->ctx); if (r == SC_ERROR_NOT_ALLOWED) /* card is already finalized */ return SC_SUCCESS; diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index 0a3c2f05..be7bbfc0 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -373,7 +373,7 @@ sc_profile_finish(struct sc_profile *profile) } return 0; -whine: sc_error(profile->card->ctx, "%s", reason); +whine: sc_debug(profile->card->ctx, "%s", reason); return SC_ERROR_INCONSISTENT_PROFILE; } @@ -590,7 +590,7 @@ sc_profile_instantiate_template(sc_profile_t *profile, if (r != SC_SUCCESS) pbuf[0] = '\0'; - sc_error(card->ctx, "Directory %s not defined in profile", pbuf); + sc_debug(card->ctx, "Directory %s not defined in profile", pbuf); return SC_ERROR_OBJECT_NOT_FOUND; } @@ -621,7 +621,7 @@ sc_profile_instantiate_template(sc_profile_t *profile, } if (match == NULL) { - sc_error(card->ctx, "No file named \"%s\" in template \"%s\"", + sc_debug(card->ctx, "No file named \"%s\" in template \"%s\"", file_name, template_name); return SC_ERROR_OBJECT_NOT_FOUND; } @@ -2059,5 +2059,5 @@ parse_error(struct state *cur, const char *fmt, ...) if ((sp = strchr(buffer, '\n')) != NULL) *sp = '\0'; - sc_error(cur->profile->card->ctx, "%s: %s", cur->filename, buffer); + sc_debug(cur->profile->card->ctx, "%s: %s", cur->filename, buffer); } diff --git a/src/tests/p15dump.c b/src/tests/p15dump.c index 7f394d15..7c934353 100644 --- a/src/tests/p15dump.c +++ b/src/tests/p15dump.c @@ -68,9 +68,7 @@ static int dump_unusedspace(void) } path.count = -1; - sc_ctx_suppress_errors_on(p15card->card->ctx); r = sc_pkcs15_read_file(p15card, &path, &buf, &buf_len, NULL); - sc_ctx_suppress_errors_off(p15card->card->ctx); if (r < 0) { if (r == SC_ERROR_FILE_NOT_FOUND) { printf("\nNo EF(UnusedSpace) file\n"); diff --git a/src/tools/cryptoflex-tool.c b/src/tools/cryptoflex-tool.c index 0181670f..1f5f290d 100644 --- a/src/tools/cryptoflex-tool.c +++ b/src/tools/cryptoflex-tool.c @@ -891,9 +891,7 @@ static int create_file(sc_file_t *file) path = file->path; if (path.len < 2) return SC_ERROR_INVALID_ARGUMENTS; - ctx->suppress_errors++; r = sc_select_file(card, &path, NULL); - ctx->suppress_errors--; if (r == 0) return 0; /* File already exists */ path.len -= 2; @@ -962,9 +960,7 @@ static int create_pin_file(const sc_path_t *inpath, int chv, const char *key_id) r = sc_select_file(card, inpath, NULL); if (r) return -1; - sc_ctx_suppress_errors_on(ctx); r = sc_select_file(card, &file_id, NULL); - sc_ctx_suppress_errors_off(ctx); if (r == 0) return 0; for (;;) { diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 8f937d98..309ae191 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -223,9 +223,7 @@ static int do_ls(int argc, char **argv) } } - ctx->suppress_errors++; r = sc_select_file(card, &path, &file); - ctx->suppress_errors--; if (r) { printf(" %02X%02X unable to select file, %s\n", cur[0], cur[1], sc_strerror(r)); } else { @@ -335,9 +333,7 @@ static int read_and_print_record_file(sc_file_t *file) int rec, r; for (rec = 1; ; rec++) { - ctx->suppress_errors++; r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR); - ctx->suppress_errors--; if (r == SC_ERROR_RECORD_NOT_FOUND) return 0; if (r < 0) { @@ -1171,10 +1167,8 @@ static int do_debug(int argc, char **argv) printf("Debug level set to %d\n", i); ctx->debug = i; if (i) { - ctx->error_file = stderr; ctx->debug_file = stdout; } else { - ctx->error_file = NULL; ctx->debug_file = NULL; } } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 17ee26c0..6113cdbb 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -530,7 +530,6 @@ do_assert_pristine(sc_card_t *in_card) * - on setcos 4.4 card, we should get 6F00 (translates to * SC_ERROR_CARD_CMD_FAILED) to indicate that no MF exists. */ - sc_ctx_suppress_errors_on(in_card->ctx); sc_format_path("2F00", &path); r = sc_select_file(in_card, &path, NULL); @@ -553,8 +552,6 @@ do_assert_pristine(sc_card_t *in_card) } - sc_ctx_suppress_errors_off(in_card->ctx); - if (!ok) { fprintf(stderr, "Card not pristine; detected (possibly incomplete) " @@ -653,7 +650,7 @@ do_init_app(struct sc_profile *profile) return sc_pkcs15init_add_app(card, profile, &args); -failed: sc_error(card->ctx, "Failed to read PIN: %s\n", sc_strerror(r)); +failed: fprintf(stderr, "Failed to read PIN: %s\n", sc_strerror(r)); return SC_ERROR_PKCS15INIT; } @@ -715,7 +712,7 @@ do_store_pin(struct sc_profile *profile) return sc_pkcs15init_store_pin(p15card, profile, &args); -failed: sc_error(card->ctx, "Failed to read PIN: %s\n", sc_strerror(r)); +failed: fprintf(stderr, "Failed to read PIN: %s\n", sc_strerror(r)); return SC_ERROR_PKCS15INIT; } @@ -1199,7 +1196,7 @@ static int do_delete_crypto_objects(sc_pkcs15_card_t *myp15card, for( ; count < 10 ; count++) { r = get_cert_info(myp15card, objs[count - 1], &has_sibling, &stop, &objs[count]); if (r < 0) - sc_error(myctx, "get_cert_info() failed: %s\n", sc_strerror(r)); + fprintf(stderr, "get_cert_info() failed: %s\n", sc_strerror(r)); else if (has_sibling) sc_debug(myctx, "Chain deletion stops with cert %s\n", sc_pkcs15_print_id( &((sc_pkcs15_cert_info_t *) objs[count - 1]->data)->id)); @@ -1215,7 +1212,7 @@ static int do_delete_crypto_objects(sc_pkcs15_card_t *myp15card, for (i = 0; i < count; i++) { r = sc_pkcs15init_delete_object(myp15card, profile, objs[i]); if (r < 0) { - sc_error(myctx, "Failed to delete object %d: %s\n", i, sc_strerror(r)); + fprintf(stderr, "Failed to delete object %d: %s\n", i, sc_strerror(r)); break; } } @@ -1615,7 +1612,7 @@ get_pin_callback(struct sc_profile *profile, hints.p15card = p15card; if ((r = sc_ui_get_pin(&hints, &secret)) < 0) { - sc_error(card->ctx, + fprintf(stderr, "Failed to read PIN from user: %s\n", sc_strerror(r)); return r; diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 3ddc2471..9b1852ca 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -286,9 +286,7 @@ static int creation_fichier_cert(sc_card_t *card) } sc_format_path("0002", &path); - sc_ctx_suppress_errors_on(ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(ctx); if(r) { if(r != SC_ERROR_FILE_NOT_FOUND) goto out; @@ -552,9 +550,7 @@ int main(int argc, char *argv[]) if(install_pin) { sc_format_path("AAAA", &path); - sc_ctx_suppress_errors_on(ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(ctx); if(r) { if(r != SC_ERROR_FILE_NOT_FOUND) goto out; @@ -689,9 +685,7 @@ int main(int argc, char *argv[]) lg = BIO_get_mem_data(mem, &p); sc_format_path("0001", &path); - sc_ctx_suppress_errors_on(ctx); r = sc_select_file(card, &path, NULL); - sc_ctx_suppress_errors_off(ctx); if(r) { if(r != SC_ERROR_FILE_NOT_FOUND) goto out; From 6a48771ce1c64859394cf74752e51a9e3b777627 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 08:51:53 +0000 Subject: [PATCH 04/57] Implement CKA_ALWAYS_AUTHENTICATE git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3722 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/pkcs11/framework-pkcs15.c | 4 ++++ src/pkcs11/pkcs11-display.c | 2 +- src/tools/pkcs11-tool.c | 5 +++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 6193990b..47ee23cf 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1965,6 +1965,10 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session, check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = TRUE; break; + case CKA_ALWAYS_AUTHENTICATE: + check_attribute_buffer(attr, sizeof(CK_BBOOL)); + *(CK_BBOOL*)attr->pValue = prkey->prv_p15obj->user_consent; + break; case CKA_PRIVATE: check_attribute_buffer(attr, sizeof(CK_BBOOL)); *(CK_BBOOL*)attr->pValue = (prkey->prv_p15obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0; diff --git a/src/pkcs11/pkcs11-display.c b/src/pkcs11/pkcs11-display.c index 57e4b1dd..870538fe 100644 --- a/src/pkcs11/pkcs11-display.c +++ b/src/pkcs11/pkcs11-display.c @@ -621,7 +621,7 @@ type_spec ck_attribute_specs[] = { { CKA_EC_POINT , "CKA_EC_POINT ", print_generic, NULL }, { CKA_SECONDARY_AUTH , "CKA_SECONDARY_AUTH ", print_generic, NULL }, { CKA_AUTH_PIN_FLAGS , "CKA_AUTH_PIN_FLAGS ", print_generic, NULL }, - { CKA_ALWAYS_AUTHENTICATE, "CKA_ALWAYS_AUTHENTICATE ", print_generic, NULL }, + { CKA_ALWAYS_AUTHENTICATE, "CKA_ALWAYS_AUTHENTICATE ", print_boolean, NULL }, { CKA_WRAP_WITH_TRUSTED , "CKA_WRAP_WITH_TRUSTED ", print_generic, NULL }, { CKA_WRAP_TEMPLATE , "CKA_WRAP_TEMPLATE ", print_generic, NULL }, { CKA_UNWRAP_TEMPLATE , "CKA_UNWRAP_TEMPLATE ", print_generic, NULL }, diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 9afcdcd4..14a00f70 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -1604,6 +1604,7 @@ ATTR_METHOD(SENSITIVE, CK_BBOOL); ATTR_METHOD(ALWAYS_SENSITIVE, CK_BBOOL); ATTR_METHOD(NEVER_EXTRACTABLE, CK_BBOOL); #endif +ATTR_METHOD(ALWAYS_AUTHENTICATE, CK_BBOOL); ATTR_METHOD(PRIVATE, CK_BBOOL); ATTR_METHOD(MODIFIABLE, CK_BBOOL); ATTR_METHOD(ENCRYPT, CK_BBOOL); @@ -1722,6 +1723,10 @@ static void show_key(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int pub) if (!*sepa) printf("none"); printf("\n"); + + if (!pub && getALWAYS_AUTHENTICATE(sess, obj)) { + printf(" Access: always authenticate\n"); + } } static void show_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj) From 17593afa600a48aa9605f249c22540c8534a436c Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 08:53:38 +0000 Subject: [PATCH 05/57] Fix iconv handle leak git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3723 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/pkcs15-esteid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 2c8c00f0..49ca7ddb 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -113,7 +113,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) if (result == (size_t) -1) return SC_ERROR_INTERNAL; *outptr = '\0'; - + iconv_close(iso_utf); snprintf(label, sizeof(label), "%s %s", name1, name2); set_string (&p15card->label, label); #endif From 847e0ade96daf32e1fc118f8490e28b9eec5c6d8 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 08:56:39 +0000 Subject: [PATCH 06/57] PKCS#11: translate SC_ERROR_CARD_UNRESPONSIVE git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3724 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/pkcs11/misc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 504a9adf..69c2136b 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -76,6 +76,8 @@ CK_RV sc_to_cryptoki_error(int rc, int reader) case SC_ERROR_INVALID_DATA: case SC_ERROR_INCORRECT_PARAMETERS: return CKR_DATA_INVALID; + case SC_ERROR_CARD_UNRESPONSIVE: + return CKR_DEVICE_ERROR; } sc_debug(context, "opensc error: %s (%d)\n", sc_strerror(rc), rc); return CKR_GENERAL_ERROR; From 446fe0f18d2178f1908e6d48a86b837319cc25e1 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 08:59:58 +0000 Subject: [PATCH 07/57] PKCS#11: Spec does not allow CKR_DEVICE_ERROR from C_Initialize git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3725 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/pkcs11/pkcs11-global.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index d6278bd8..4e17fca8 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -203,7 +203,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) rc = sc_context_create(&context, &ctx_opts); if (rc != SC_SUCCESS) { - rv = CKR_DEVICE_ERROR; + rv = CKR_GENERAL_ERROR; goto out; } From cd5aff8ea01fc37819c10a6bc543348d47a48c95 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 09:03:33 +0000 Subject: [PATCH 08/57] PC/SC: More return codes are handled. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3726 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/internal-winscard.h | 2 ++ src/libopensc/reader-pcsc.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/libopensc/internal-winscard.h b/src/libopensc/internal-winscard.h index e671817e..b7b0272d 100644 --- a/src/libopensc/internal-winscard.h +++ b/src/libopensc/internal-winscard.h @@ -49,6 +49,8 @@ typedef unsigned __int8 uint8_t; #define SCARD_E_INVALID_HANDLE 0x80100003 /**< The supplied handle was invalid. */ #define SCARD_E_TIMEOUT 0x8010000A /**< The user-specified timeout value has expired. */ #define SCARD_E_SHARING_VIOLATION 0x8010000B /**< The smart card cannot be accessed because of other connections outstanding. */ +#define SCARD_E_NO_SMARTCARD 0x8010000C /**< The operation requires a smart card, but no smart card is currently in the device. */ +#define SCARD_E_PROTO_MISMATCH 0x8010000F /**< The requested protocols are incompatible with the protocol currently in use with the smart card. */ #define SCARD_E_NOT_TRANSACTED 0x80100016 /**< An attempt was made to end a non-existent transaction. */ #define SCARD_E_READER_UNAVAILABLE 0x80100017 /**< The specified reader is not currently available for use. */ #define SCARD_E_NO_SERVICE 0x8010001D /**< The Smart card resource manager is not running. */ diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index b6abdbbf..6f2ba01d 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -113,6 +113,10 @@ static int pcsc_ret_to_error(long rv) case SCARD_E_NO_SERVICE: /* If the service is (auto)started, there could be readers later */ return SC_ERROR_NO_READERS_FOUND; + case SCARD_E_NO_SMARTCARD: + return SC_ERROR_CARD_NOT_PRESENT; + case SCARD_E_PROTO_MISMATCH: /* Should not happen */ + return SC_ERROR_READER; default: return SC_ERROR_UNKNOWN; } From 1aed8cdec41ab1e242c345946b03a29480d860fe Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 09:08:16 +0000 Subject: [PATCH 09/57] PKCS#15-emu: remove dead code git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3727 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/pkcs15-syn.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index b66f7ea2..58a2e378 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -185,15 +185,6 @@ out: if (r == SC_SUCCESS) { return r; } -static int emu_detect_card(sc_card_t *card, const scconf_block *blk, int *force) -{ - int ret = 0; - - /* TBD */ - - return ret; -} - static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf) { sc_card_t *card = p15card->card; @@ -207,10 +198,6 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf) driver = conf->name->data; - r = emu_detect_card(card, conf, &force); - if (r < 0) - return SC_ERROR_INTERNAL; - init_func = NULL; init_func_ex = NULL; From 7df1c600f19400cc8e080feb1fa9ac020c7e4179 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 09:15:58 +0000 Subject: [PATCH 10/57] Remove empty files: emv.c, emv.h git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3728 c6295689-39f2-0310-b995-f0e70906c6a9 --- solaris/proto | 1 - src/include/opensc/Makefile.am | 1 - src/libopensc/Makefile.am | 4 ++-- src/libopensc/Makefile.mak | 4 ++-- src/libopensc/emv.c | 24 -------------------- src/libopensc/emv.h | 41 ---------------------------------- 6 files changed, 4 insertions(+), 71 deletions(-) delete mode 100644 src/libopensc/emv.c delete mode 100644 src/libopensc/emv.h diff --git a/solaris/proto b/solaris/proto index 4063003d..665d611b 100644 --- a/solaris/proto +++ b/solaris/proto @@ -92,7 +92,6 @@ f none usr/include/opensc/rsaref/win32.h 0644 root bin f none usr/include/opensc/scconf.h 0644 root bin f none usr/include/opensc/opensc.h 0644 root bin f none usr/include/opensc/pkcs15.h 0644 root bin -f none usr/include/opensc/emv.h 0644 root bin f none usr/include/opensc/cardctl.h 0644 root bin f none usr/include/opensc/asn1.h 0644 root bin f none usr/include/opensc/log.h 0644 root bin diff --git a/src/include/opensc/Makefile.am b/src/include/opensc/Makefile.am index d58c49a9..4723a4ef 100644 --- a/src/include/opensc/Makefile.am +++ b/src/include/opensc/Makefile.am @@ -6,7 +6,6 @@ all-local: @$(LN_S) $(top_srcdir)/src/libopensc/asn1.h asn1.h @$(LN_S) $(top_srcdir)/src/libopensc/cardctl.h cardctl.h @$(LN_S) $(top_srcdir)/src/libopensc/cards.h cards.h - @$(LN_S) $(top_srcdir)/src/libopensc/emv.h emv.h @$(LN_S) $(top_srcdir)/src/libopensc/errors.h errors.h @$(LN_S) $(top_srcdir)/src/libopensc/log.h log.h @$(LN_S) $(top_srcdir)/src/libopensc/opensc.h opensc.h diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index ae3542b9..01af7503 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -8,7 +8,7 @@ EXTRA_DIST = Makefile.mak bin_SCRIPTS = opensc-config lib_LTLIBRARIES = libopensc.la openscinclude_HEADERS = \ - opensc.h pkcs15.h emv.h \ + opensc.h pkcs15.h \ cardctl.h asn1.h log.h ui.h \ errors.h types.h compression.h noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h \ @@ -30,7 +30,7 @@ libopensc_la_SOURCES = \ pkcs15-wrap.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \ pkcs15-gemsafeV1.c \ \ - emv.c muscle.c muscle-filesystem.c \ + muscle.c muscle-filesystem.c \ \ ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c \ \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index a06fa827..9ec97f16 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -4,7 +4,7 @@ TOPDIR = ..\.. TARGET = opensc.dll opensc_a.lib HEADERS = \ - asn1.h cardctl.h cards.h emv.h errors.h \ + asn1.h cardctl.h cards.h errors.h \ log.h opensc.h pkcs15.h types.h ui.h HEADERSDIR = $(TOPDIR)\src\include\opensc @@ -18,7 +18,7 @@ OBJECTS = \ pkcs15-wrap.obj pkcs15-algo.obj pkcs15-cache.obj pkcs15-syn.obj \ pkcs15-gemsafeV1.obj \ \ - emv.obj muscle.obj muscle-filesystem.obj \ + muscle.obj muscle-filesystem.obj \ \ ctbcs.obj reader-ctapi.obj reader-pcsc.obj reader-openct.obj \ \ diff --git a/src/libopensc/emv.c b/src/libopensc/emv.c deleted file mode 100644 index 94a05ba7..00000000 --- a/src/libopensc/emv.c +++ /dev/null @@ -1,24 +0,0 @@ -/* - * emv.c: EMV functions - * - * Copyright (C) 2001, 2002 Juha Yrjölä - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "internal.h" -#include "emv.h" - -/* FIXME: Implement */ diff --git a/src/libopensc/emv.h b/src/libopensc/emv.h deleted file mode 100644 index 2e537442..00000000 --- a/src/libopensc/emv.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * emv.h: OpenSC EMV header file - * - * Copyright (C) 2001, 2002 Juha Yrjölä - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _OPENSC_EMV_H -#define _OPENSC_EMV_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct sc_emv_card { - struct sc_card *card; -}; - -int sc_emv_bind(struct sc_card *card, struct sc_emv_card **emv_card); -int sc_emv_unbind(struct sc_emv_card *emv_card); - -#ifdef __cplusplus -} -#endif - -#endif From a64cdc1d8e8bfbda24c600fb0c31bc67d4513db3 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 09:35:15 +0000 Subject: [PATCH 11/57] sc_error removal missing bits git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3729 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/log.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/log.h b/src/libopensc/log.h index 04dff00f..ee4ea712 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -66,13 +66,13 @@ void sc_hex_dump(struct sc_context *ctx, const u8 * buf, size_t len, char *out, #define SC_TEST_RET(ctx, r, text) do { \ int _ret = (r); \ if (_ret < 0) { \ - sc_do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, "%s: %s\n", (text), sc_strerror(_ret)); \ + sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "%s: %s\n", (text), sc_strerror(_ret)); \ return _ret; \ } \ } while(0) #define sc_perror(ctx, errno, str) { \ - sc_do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, "%s: %s\n", str, sc_strerror(errno)); \ + sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "%s: %s\n", str, sc_strerror(errno)); \ } #ifdef __cplusplus From f6d4da7919cc5a5e16b536238d13fbe14c44f171 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 09:48:56 +0000 Subject: [PATCH 12/57] PC/SC: Improve core and pinpad code * Make opensc-tool -l display pinpad capabilities, if available * Detect reader capabilities when a reader is found, not when a connection to a card is opened * Fix unpadded PIN block parameters to not be rejected by the latest free CCID driver * When locking the card and it has been reset by some other application (or re-attached), clear cache and lock again * Enable pinpad detection by default git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3730 c6295689-39f2-0310-b995-f0e70906c6a9 --- etc/opensc.conf.in | 4 +- src/libopensc/card.c | 9 +- src/libopensc/internal-winscard.h | 1 + src/libopensc/reader-pcsc.c | 240 +++++++++++++++--------------- src/tools/opensc-tool.c | 6 +- 5 files changed, 135 insertions(+), 125 deletions(-) diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 812c0411..3eb0899e 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -78,8 +78,8 @@ app default { # transaction_reset = true; # # Enable pinpad if detected (PC/SC v2.0.2 Part 10) - # Default: false - # enable_pinpad = true; + # Default: true + # enable_pinpad = false; # # Use specific pcsc provider. # Default: @DEFAULT_PCSC_PROVIDER@ diff --git a/src/libopensc/card.c b/src/libopensc/card.c index b672bc10..f49076bf 100644 --- a/src/libopensc/card.c +++ b/src/libopensc/card.c @@ -290,8 +290,15 @@ int sc_lock(sc_card_t *card) if (r != SC_SUCCESS) return r; if (card->lock_count == 0) { - if (card->reader->ops->lock != NULL) + if (card->reader->ops->lock != NULL) { r = card->reader->ops->lock(card->reader, card->slot); + if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) { + /* invalidate cache */ + memset(&card->cache, 0, sizeof(card->cache)); + card->cache_valid = 0; + r = card->reader->ops->lock(card->reader, card->slot); + } + } if (r == 0) card->cache_valid = 1; } diff --git a/src/libopensc/internal-winscard.h b/src/libopensc/internal-winscard.h index b7b0272d..9ab5a773 100644 --- a/src/libopensc/internal-winscard.h +++ b/src/libopensc/internal-winscard.h @@ -37,6 +37,7 @@ typedef unsigned __int8 uint8_t; #define SCARD_SHARE_EXCLUSIVE 0x0001 /**< Exclusive mode only */ #define SCARD_SHARE_SHARED 0x0002 /**< Shared mode only */ +#define SCARD_SHARE_DIRECT 0x0003 /**< Raw mode only */ #define SCARD_LEAVE_CARD 0x0000 /**< Do nothing on close */ #define SCARD_RESET_CARD 0x0001 /**< Reset on close */ diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 6f2ba01d..80b7de9b 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -20,7 +20,6 @@ #include "internal.h" #ifdef ENABLE_PCSC -#include "ctbcs.h" #include #include #include @@ -47,9 +46,6 @@ #define GET_PRIV_DATA(r) ((struct pcsc_private_data *) (r)->drv_data) #define GET_SLOT_DATA(r) ((struct pcsc_slot_data *) (r)->drv_data) -static int part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, - struct sc_pin_cmd_data *data); - struct pcsc_global_private_data { SCARDCONTEXT pcsc_ctx; int enable_pinpad; @@ -549,86 +545,6 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot) sc_debug(reader->ctx, "Proto after reconnect = %d", slot->active_protocol); } } - - /* check for pinpad support */ - if (priv->gpriv->SCardControl != NULL) { - sc_debug(reader->ctx, "Requesting reader features ... "); - - rv = priv->gpriv->SCardControl(pslot->pcsc_card, CM_IOCTL_GET_FEATURE_REQUEST, NULL, - 0, feature_buf, sizeof(feature_buf), &feature_len); - if (rv != SCARD_S_SUCCESS) { - sc_debug(reader->ctx, "SCardControl failed %08x", rv); - } - else { - if ((feature_len % sizeof(PCSC_TLV_STRUCTURE)) != 0) { - sc_debug(reader->ctx, "Inconsistent TLV from reader!"); - } - else { - char *log_disabled = "but it's disabled in configuration file"; - /* get the number of elements instead of the complete size */ - feature_len /= sizeof(PCSC_TLV_STRUCTURE); - - pcsc_tlv = (PCSC_TLV_STRUCTURE *)feature_buf; - for (i = 0; i < feature_len; i++) { - if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_DIRECT) { - pslot->verify_ioctl = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_START) { - pslot->verify_ioctl_start = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_FINISH) { - pslot->verify_ioctl_finish = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_DIRECT) { - pslot->modify_ioctl = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_START) { - pslot->modify_ioctl_start = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_FINISH) { - pslot->modify_ioctl_finish = ntohl(pcsc_tlv[i].value); - } else if (pcsc_tlv[i].tag == FEATURE_IFD_PIN_PROPERTIES) { - display_ioctl = ntohl(pcsc_tlv[i].value); - } else { - sc_debug(reader->ctx, "Reader feature %02x is not supported", pcsc_tlv[i].tag); - } - } - - /* Set slot capabilities based on detected IOCTLs */ - if (pslot->verify_ioctl || (pslot->verify_ioctl_start && pslot->verify_ioctl_finish)) { - char *log_text = "Reader supports pinpad PIN verification"; - if (priv->gpriv->enable_pinpad) { - sc_debug(reader->ctx, log_text); - slot->capabilities |= SC_SLOT_CAP_PIN_PAD; - } else { - sc_debug(reader->ctx, "%s %s", log_text, log_disabled); - } - } - - if (pslot->modify_ioctl || (pslot->modify_ioctl_start && pslot->modify_ioctl_finish)) { - char *log_text = "Reader supports pinpad PIN modification"; - if (priv->gpriv->enable_pinpad) { - sc_debug(reader->ctx, log_text); - slot->capabilities |= SC_SLOT_CAP_PIN_PAD; - } else { - sc_debug(reader->ctx, "%s %s", log_text, log_disabled); - } - } - - if (display_ioctl) { - rcount = sizeof(rbuf); - r = pcsc_internal_transmit(reader, slot, NULL, 0, rbuf, &rcount, display_ioctl); - if (r == SC_SUCCESS) { - if (rcount != sizeof(PIN_PROPERTIES_STRUCTURE)) { - PIN_PROPERTIES_STRUCTURE *caps = (PIN_PROPERTIES_STRUCTURE *)rbuf; - if (caps->wLcdLayout > 0) { - sc_debug(reader->ctx, "Reader has a display: %04X", caps->wLcdLayout); - slot->capabilities |= SC_SLOT_CAP_DISPLAY; - } else - sc_debug(reader->ctx, "Reader does not have a display."); - } else { - sc_debug(reader->ctx, "Returned PIN properties structure has bad length (%d)", rcount); - } - } - } - } - } - } return SC_SUCCESS; } @@ -760,7 +676,7 @@ static int pcsc_init(sc_context_t *ctx, void **reader_data) gpriv->connect_reset = 1; gpriv->connect_exclusive = 0; gpriv->transaction_reset = 0; - gpriv->enable_pinpad = 0; + gpriv->enable_pinpad = 1; gpriv->provider_library = DEFAULT_PCSC_PROVIDER; gpriv->pcsc_ctx = -1; @@ -866,9 +782,14 @@ static int pcsc_finish(sc_context_t *ctx, void *prv_data) static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) { + DWORD active_proto, protocol; + SCARDHANDLE card_handle; + int r; + u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE]; + PCSC_TLV_STRUCTURE *pcsc_tlv; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) prv_data; LONG rv; - DWORD reader_buf_size; + DWORD reader_buf_size, rcount, i, feature_len, display_ioctl; char *reader_buf = NULL, *reader_name; const char *mszGroups = NULL; int ret = SC_ERROR_INTERNAL; @@ -988,8 +909,99 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) ret = SC_SUCCESS; /* silent ignore */ goto err1; } - refresh_slot_attributes(reader, slot); + /* check for pinpad support */ + if (gpriv->SCardControl != NULL) { + sc_debug(ctx, "Requesting reader features ... "); +#ifdef __APPLE__ /* 10.5.7 does not support 0 as protocol identifier */ + rv = gpriv->SCardConnect(gpriv->pcsc_ctx, priv->reader_name, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_ANY, &card_handle, &active_proto); +#else + rv = gpriv->SCardConnect(gpriv->pcsc_ctx, priv->reader_name, SCARD_SHARE_DIRECT, 0, &card_handle, &active_proto); + if (rv == SCARD_E_SHARING_VIOLATION) /* Assume that there is a card in the reader in shared mode */ + rv = gpriv->SCardConnect(gpriv->pcsc_ctx, priv->reader_name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY, &card_handle, &active_proto); +#endif + if (rv == SCARD_S_SUCCESS) { + rv = gpriv->SCardControl(card_handle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, feature_buf, sizeof(feature_buf), &feature_len); + if (rv != SCARD_S_SUCCESS) { + sc_debug(ctx, "SCardControl failed %08x", rv); + } + else { + if ((feature_len % sizeof(PCSC_TLV_STRUCTURE)) != 0) { + sc_debug(ctx, "Inconsistent TLV from reader!"); + } + else { + char *log_disabled = "but it's disabled in configuration file"; + /* get the number of elements instead of the complete size */ + feature_len /= sizeof(PCSC_TLV_STRUCTURE); + + pcsc_tlv = (PCSC_TLV_STRUCTURE *)feature_buf; + for (i = 0; i < feature_len; i++) { + sc_debug(ctx, "Reader feature %02x detected", pcsc_tlv[i].tag); + if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_DIRECT) { + pslot->verify_ioctl = ntohl(pcsc_tlv[i].value); + } else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_START) { + pslot->verify_ioctl_start = ntohl(pcsc_tlv[i].value); + } else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_FINISH) { + pslot->verify_ioctl_finish = ntohl(pcsc_tlv[i].value); + } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_DIRECT) { + pslot->modify_ioctl = ntohl(pcsc_tlv[i].value); + } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_START) { + pslot->modify_ioctl_start = ntohl(pcsc_tlv[i].value); + } else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_FINISH) { + pslot->modify_ioctl_finish = ntohl(pcsc_tlv[i].value); + } else if (pcsc_tlv[i].tag == FEATURE_IFD_PIN_PROPERTIES) { + display_ioctl = ntohl(pcsc_tlv[i].value); + } else { + sc_debug(ctx, "Reader feature %02x is not supported", pcsc_tlv[i].tag); + } + } + + /* Set slot capabilities based on detected IOCTLs */ + if (pslot->verify_ioctl || (pslot->verify_ioctl_start && pslot->verify_ioctl_finish)) { + char *log_text = "Reader supports pinpad PIN verification"; + if (priv->gpriv->enable_pinpad) { + sc_debug(ctx, log_text); + slot->capabilities |= SC_SLOT_CAP_PIN_PAD; + } else { + sc_debug(ctx, "%s %s", log_text, log_disabled); + } + } + + if (pslot->modify_ioctl || (pslot->modify_ioctl_start && pslot->modify_ioctl_finish)) { + char *log_text = "Reader supports pinpad PIN modification"; + if (priv->gpriv->enable_pinpad) { + sc_debug(ctx, log_text); + slot->capabilities |= SC_SLOT_CAP_PIN_PAD; + } else { + sc_debug(ctx, "%s %s", log_text, log_disabled); + } + } + + if (display_ioctl) { + rcount = sizeof(rbuf); + rv = gpriv->SCardControl(card_handle, display_ioctl, NULL, 0, rbuf, sizeof(rbuf), &rcount); + if (r == SC_SUCCESS) { + if (rcount != sizeof(PIN_PROPERTIES_STRUCTURE)) { + PIN_PROPERTIES_STRUCTURE *caps = (PIN_PROPERTIES_STRUCTURE *)rbuf; + if (caps->wLcdLayout > 0) { + sc_debug(ctx, "Reader has a display: %04X", caps->wLcdLayout); + slot->capabilities |= SC_SLOT_CAP_DISPLAY; + } else + sc_debug(ctx, "Reader does not have a display."); + } else { + sc_debug(ctx, "Returned PIN properties structure has bad length (%d)", rcount); + } + } + } + } + } + gpriv->SCardDisconnect(card_handle, SCARD_LEAVE_CARD); + } + else { + sc_debug(ctx, "SCardConnect failed %08x", rv); + } + } + refresh_slot_attributes(reader, slot); continue; err1: @@ -1019,36 +1031,6 @@ out: SC_FUNC_RETURN(ctx, 3, ret); } -static int -pcsc_pin_cmd(sc_reader_t *reader, sc_slot_info_t * slot, struct sc_pin_cmd_data *data) -{ - if (slot->capabilities & SC_SLOT_CAP_PIN_PAD) { - return part10_pin_cmd(reader, slot, data); - } else { - /* XXX: probably dead code */ - return ctbcs_pin_cmd(reader, slot, data); - } -} - -struct sc_reader_driver * sc_get_pcsc_driver(void) -{ - pcsc_ops.init = pcsc_init; - pcsc_ops.finish = pcsc_finish; - pcsc_ops.detect_readers = pcsc_detect_readers; - pcsc_ops.transmit = pcsc_transmit; - pcsc_ops.detect_card_presence = pcsc_detect_card_presence; - pcsc_ops.lock = pcsc_lock; - pcsc_ops.unlock = pcsc_unlock; - pcsc_ops.release = pcsc_release; - pcsc_ops.connect = pcsc_connect; - pcsc_ops.disconnect = pcsc_disconnect; - pcsc_ops.perform_verify = pcsc_pin_cmd; - pcsc_ops.wait_for_event = pcsc_wait_for_event; - pcsc_ops.reset = pcsc_reset; - - return &pcsc_drv; -} - /* * Pinpad support, based on PC/SC v2 Part 10 interface * Similar to CCID in spirit. @@ -1104,7 +1086,7 @@ static int part10_build_verify_pin_block(u8 * buf, size_t * size, sc_slot_info_t if (data->pin1.encoding == SC_PIN_ENCODING_GLP) { /* GLP PIN length is encoded in 4 bits and block size is always 8 bytes */ tmp |= 0x40 | 0x08; - } else if (data->pin1.encoding == SC_PIN_ENCODING_ASCII && data->pin1.pad_length) { + } else if (data->pin1.encoding == SC_PIN_ENCODING_ASCII && data->flags & SC_PIN_CMD_NEED_PADDING) { tmp |= data->pin1.pad_length; } pin_verify->bmPINBlockString = tmp; @@ -1266,7 +1248,7 @@ static int part10_build_modify_pin_block(u8 * buf, size_t * size, sc_slot_info_t /* Do the PIN command */ static int -part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, +pcsc_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, struct sc_pin_cmd_data *data) { struct pcsc_private_data *priv = GET_PRIV_DATA(reader); @@ -1366,5 +1348,25 @@ part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot, /* PIN command completed, all is good */ return SC_SUCCESS; } + +struct sc_reader_driver * sc_get_pcsc_driver(void) +{ + pcsc_ops.init = pcsc_init; + pcsc_ops.finish = pcsc_finish; + pcsc_ops.detect_readers = pcsc_detect_readers; + pcsc_ops.transmit = pcsc_transmit; + pcsc_ops.detect_card_presence = pcsc_detect_card_presence; + pcsc_ops.lock = pcsc_lock; + pcsc_ops.unlock = pcsc_unlock; + pcsc_ops.release = pcsc_release; + pcsc_ops.connect = pcsc_connect; + pcsc_ops.disconnect = pcsc_disconnect; + pcsc_ops.perform_verify = pcsc_pin_cmd; + pcsc_ops.wait_for_event = pcsc_wait_for_event; + pcsc_ops.reset = pcsc_reset; + + return &pcsc_drv; +} + #endif /* HAVE_PCSC */ diff --git a/src/tools/opensc-tool.c b/src/tools/opensc-tool.c index 76c21349..3df59697 100644 --- a/src/tools/opensc-tool.c +++ b/src/tools/opensc-tool.c @@ -249,11 +249,11 @@ static int list_readers(void) printf("No smart card readers found.\n"); return 0; } - printf("Readers known about:\n"); - printf("Nr. Driver Name\n"); + printf("Nr. Driver Features Name\n"); for (i = 0; i < rcount; i++) { sc_reader_t *screader = sc_ctx_get_reader(ctx, i); - printf("%-7d%-11s%s\n", i, screader->driver->short_name, + printf("%-7d%-11s%-10s%s\n", i, screader->driver->short_name, + screader->slot[0].capabilities & SC_SLOT_CAP_PIN_PAD ? "PINpad":"", screader->name); } return 0; From a614dff522e24196b72ac2c8839450bc21ab7148 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 10:05:40 +0000 Subject: [PATCH 13/57] PKCS#11: Implement more token flags that describe available PIN retries. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3731 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/pkcs15.h | 1 + src/pkcs11/framework-pkcs15.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 6bb05a19..64a237f7 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -71,6 +71,7 @@ struct sc_pkcs15_pin_info { u8 pad_char; struct sc_path path; int tries_left; + int max_tries; unsigned int magic; }; diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 47ee23cf..6ee7200f 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -677,6 +677,14 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *card, snprintf(tmp, sizeof(tmp), "%s", card->label); } slot->token_info.flags |= CKF_LOGIN_REQUIRED; + if (pin_info->tries_left >= 0) { + if (pin_info->tries_left == 1) + slot->token_info.flags |= CKF_USER_PIN_FINAL_TRY; + else if (pin_info->tries_left == 0) + slot->token_info.flags |= CKF_USER_PIN_LOCKED; + else if (pin_info->max_tries && pin_info->tries_left && pin_info->tries_left < pin_info->max_tries) + slot->token_info.flags |= CKF_USER_PIN_COUNT_LOW; + } } else snprintf(tmp, sizeof(tmp), "%s", card->label); strcpy_bp(slot->token_info.label, tmp, 32); @@ -689,6 +697,8 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *card, slot->token_info.ulMaxPinLen = 8; slot->token_info.ulMinPinLen = 4; } + if (card->flags & SC_PKCS15_CARD_FLAG_EMULATED) + slot->token_info.flags |= CKF_WRITE_PROTECTED; sc_debug(context, "Initialized token '%s'\n", tmp); } From 831d1a539e288472eafea3318f9390312f557245 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 10:12:24 +0000 Subject: [PATCH 14/57] PKCS#11: Fix a crash in C_GetMechanismList if pulCount is NULL git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3732 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/pkcs11/mechanism.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 122dee7b..99b9f912 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -80,10 +80,13 @@ sc_pkcs11_get_mechanism_list(struct sc_pkcs11_card *p11card, unsigned int n, count = 0; int rv; + if (!pulCount) + return CKR_ARGUMENTS_BAD; + for (n = 0; n < p11card->nmechanisms; n++) { if (!(mt = p11card->mechanisms[n])) continue; - if (count < *pulCount && pList) + if (pList && count < *pulCount) pList[count] = mt->mech; count++; } From 6155ae366ace67f4f98cad8aea3add7be72b7491 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 14 Sep 2009 12:04:24 +0000 Subject: [PATCH 15/57] Add back needed debug level check. Thanks to Aleksey Samsonov git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3733 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/log.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libopensc/log.h b/src/libopensc/log.h index ee4ea712..254bdae0 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -59,7 +59,9 @@ void sc_hex_dump(struct sc_context *ctx, const u8 * buf, size_t len, char *out, #define SC_FUNC_RETURN(ctx, level, r) do { \ int _ret = r; \ - sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "returning with: %d\n", _ret); \ + if (ctx->debug >= level) { \ + sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "returning with: %d\n", _ret); \ + } \ return _ret; \ } while(0) From 0f4092f12d5c335a44cec30ffde78c83bd558c76 Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 15 Sep 2009 07:50:46 +0000 Subject: [PATCH 16/57] Fix "log.h:64:4: warning: backslash and newline separated by space" git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3734 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/log.h b/src/libopensc/log.h index 254bdae0..acdc1343 100644 --- a/src/libopensc/log.h +++ b/src/libopensc/log.h @@ -61,7 +61,7 @@ void sc_hex_dump(struct sc_context *ctx, const u8 * buf, size_t len, char *out, int _ret = r; \ if (ctx->debug >= level) { \ sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "returning with: %d\n", _ret); \ - } \ + } \ return _ret; \ } while(0) From b6f9345ea1f443a5571ede4a781c713218deecde Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 15 Sep 2009 07:51:50 +0000 Subject: [PATCH 17/57] Improve EMV and default driver git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3735 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-default.c | 14 ++++++-------- src/libopensc/card-emv.c | 12 +++++------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/libopensc/card-default.c b/src/libopensc/card-default.c index ab7083fd..70e5c26c 100644 --- a/src/libopensc/card-default.c +++ b/src/libopensc/card-default.c @@ -31,7 +31,7 @@ static struct sc_card_driver default_drv = { static int default_finish(sc_card_t *card) { - return 0; + return SC_SUCCESS; } static int default_match_card(sc_card_t *card) @@ -84,12 +84,12 @@ static int autodetect_class(sc_card_t *card) if (card->ctx->debug >= 2) sc_debug(card->ctx, "SELECT FILE returned %d bytes\n", apdu.resplen); - return 0; + return SC_SUCCESS; } if (rbuf[0] == 0x6F) { if (card->ctx->debug >= 2) sc_debug(card->ctx, "SELECT FILE seems to behave according to ISO 7816-4\n"); - return 0; + return SC_SUCCESS; } if (rbuf[0] == 0x00 && rbuf[1] == 0x00) { struct sc_card_driver *drv; @@ -97,9 +97,9 @@ static int autodetect_class(sc_card_t *card) sc_debug(card->ctx, "SELECT FILE seems to return Schlumberger 'flex stuff\n"); drv = sc_get_cryptoflex_driver(); card->ops->select_file = drv->ops->select_file; - return 0; + return SC_SUCCESS; } - return 0; + return SC_SUCCESS; } static int default_init(sc_card_t *card) @@ -114,7 +114,7 @@ static int default_init(sc_card_t *card) return SC_ERROR_INVALID_CARD; } - return 0; + return SC_SUCCESS; } static struct sc_card_driver * sc_get_driver(void) @@ -129,9 +129,7 @@ static struct sc_card_driver * sc_get_driver(void) return &default_drv; } -#if 1 struct sc_card_driver * sc_get_default_driver(void) { return sc_get_driver(); } -#endif diff --git a/src/libopensc/card-emv.c b/src/libopensc/card-emv.c index f805d2cc..cb8ca00b 100644 --- a/src/libopensc/card-emv.c +++ b/src/libopensc/card-emv.c @@ -23,7 +23,7 @@ static struct sc_card_operations emv_ops; static struct sc_card_driver emv_drv = { - "EMV compatible cards", + "EMV cards (unsupported)", "emv", &emv_ops, NULL, 0, NULL @@ -31,7 +31,7 @@ static struct sc_card_driver emv_drv = { static int emv_finish(sc_card_t *card) { - return 0; + return SC_SUCCESS; } static int parse_atr(const u8 *atr, size_t atr_len, int *t0_out, int *tx1, int *tx2, @@ -120,7 +120,7 @@ static int emv_init(sc_card_t *card) card->drv_data = NULL; card->cla = 0x00; - return 0; + return SC_SUCCESS; } static int emv_select_file(sc_card_t *card, const sc_path_t *path, @@ -137,7 +137,7 @@ static int emv_select_file(sc_card_t *card, const sc_path_t *path, (*file)->type = SC_FILE_TYPE_DF; if (file != NULL && (*file)->namelen) (*file)->type = SC_FILE_TYPE_DF; - return 0; + return SC_SUCCESS; } static struct sc_card_driver * sc_get_driver(void) @@ -147,15 +147,13 @@ static struct sc_card_driver * sc_get_driver(void) emv_ops = *iso_drv->ops; emv_ops.match_card = emv_match_card; emv_ops.init = emv_init; - emv_ops.finish = emv_finish; + emv_ops.finish = emv_finish; emv_ops.select_file = emv_select_file; return &emv_drv; } -#if 1 struct sc_card_driver * sc_get_emv_driver(void) { return sc_get_driver(); } -#endif From 46a4b5b70ec560817d93f8afb202e67010556915 Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 15 Sep 2009 07:59:20 +0000 Subject: [PATCH 18/57] EstEID: Fix compiler warnings, add support for PIN retries related PKCS#11 token flags, add a version number for debugging. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3736 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/pkcs15-esteid.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libopensc/pkcs15-esteid.c b/src/libopensc/pkcs15-esteid.c index 49ca7ddb..77632872 100644 --- a/src/libopensc/pkcs15-esteid.c +++ b/src/libopensc/pkcs15-esteid.c @@ -65,7 +65,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) iconv_t iso_utf; char *inptr, *outptr; size_t inbytes, outbytes, result; - unsigned char label[64], name1[32], name2[32]; + char label[64], name1[32], name2[32]; #endif unsigned char buff[128]; int r, i, flags; @@ -73,6 +73,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) set_string (&p15card->label, "ID-kaart"); set_string (&p15card->manufacturer_id, "AS Sertifitseerimiskeskus"); + p15card->version = 2; /* Increases as the code changes for EstEID happen, not only in this file */ /* Select application directory */ sc_format_path ("3f00eeee5044", &tmppath); @@ -94,7 +95,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) r = sc_read_record (card, SC_ESTEID_PD_GIVEN_NAMES1, buff, sizeof(buff), SC_RECORD_BY_REC_NR); SC_TEST_RET (card->ctx, r, "read name1 failed"); - inptr = buff; + inptr = (char *) buff; outptr = name1; inbytes = r; outbytes = 32; @@ -105,7 +106,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) r = sc_read_record (card, SC_ESTEID_PD_SURNAME, buff, sizeof(buff), SC_RECORD_BY_REC_NR); SC_TEST_RET (card->ctx, r, "read name2 failed"); - inptr = buff; + inptr = (char *) buff; outptr = name2; inbytes = r; outbytes = 32; @@ -192,6 +193,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card) pin_info.max_length = 12; pin_info.pad_char = '\0'; pin_info.tries_left = (int)tries_left; + pin_info.max_tries = 3; strlcpy(pin_obj.label, esteid_pin_names[i], sizeof(pin_obj.label)); pin_obj.flags = esteid_pin_flags[i]; From e350239b37ee4cb355d838c873309b96fac46d3c Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 15 Sep 2009 12:29:17 +0000 Subject: [PATCH 19/57] Fix debug file closing. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3737 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/ctx.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index c64ce03b..efde1157 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -85,8 +85,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "rutoken", (void *(*)(void)) sc_get_rutoken_driver }, { "rutoken_ecp",(void *(*)(void)) sc_get_rtecp_driver }, { "westcos", (void *(*)(void)) sc_get_westcos_driver }, - /* emv is not really used, not sure if it works, but it conflicts with - muscle and rutoken driver, thus has to be after them */ + /* emv is not really implemented */ { "emv", (void *(*)(void)) sc_get_emv_driver }, /* The default driver should be last, as it handles all the * unrecognized cards. */ @@ -176,7 +175,7 @@ static void add_internal_drvs(struct _sc_ctx_options *opts, int type) static void set_defaults(sc_context_t *ctx, struct _sc_ctx_options *opts) { ctx->debug = 0; - if (ctx->debug_file && ctx->debug_file != stderr) + if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) fclose(ctx->debug_file); ctx->debug_file = stderr; ctx->forced_driver = NULL; @@ -199,7 +198,7 @@ static int load_parameters(sc_context_t *ctx, scconf_block *block, val = scconf_get_str(block, "debug_file", NULL); if (val) { - if (ctx->debug_file && (ctx->debug_file != stderr || ctx->debug_file != stdout)) + if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout)) fclose(ctx->debug_file); if (!strcmp(val, "stdout")) ctx->debug_file = stdout; From 75cee4ff8e481072753327e1f2a2fcbfa06e4e58 Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 15 Sep 2009 12:33:35 +0000 Subject: [PATCH 20/57] PC/SC: Fix display detection and clean up git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3738 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/reader-pcsc.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 80b7de9b..d5ac73fb 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -505,10 +505,6 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot) struct pcsc_private_data *priv = GET_PRIV_DATA(reader); struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot); int r; - u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE]; - size_t rcount; - DWORD i, feature_len, display_ioctl; - PCSC_TLV_STRUCTURE *pcsc_tlv; r = refresh_slot_attributes(reader, slot); if (r) @@ -782,14 +778,13 @@ static int pcsc_finish(sc_context_t *ctx, void *prv_data) static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) { - DWORD active_proto, protocol; + DWORD active_proto; SCARDHANDLE card_handle; - int r; u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE]; PCSC_TLV_STRUCTURE *pcsc_tlv; struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) prv_data; LONG rv; - DWORD reader_buf_size, rcount, i, feature_len, display_ioctl; + DWORD reader_buf_size, rcount, feature_len, display_ioctl; char *reader_buf = NULL, *reader_name; const char *mszGroups = NULL; int ret = SC_ERROR_INTERNAL; @@ -854,7 +849,7 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) struct pcsc_private_data *priv = NULL; struct pcsc_slot_data *pslot = NULL; sc_slot_info_t *slot = NULL; - int i; + unsigned int i; int found = 0; for (i=0;i < sc_ctx_get_reader_count (ctx) && !found;i++) { @@ -980,8 +975,8 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) if (display_ioctl) { rcount = sizeof(rbuf); rv = gpriv->SCardControl(card_handle, display_ioctl, NULL, 0, rbuf, sizeof(rbuf), &rcount); - if (r == SC_SUCCESS) { - if (rcount != sizeof(PIN_PROPERTIES_STRUCTURE)) { + if (rv == SCARD_S_SUCCESS) { + if (rcount == sizeof(PIN_PROPERTIES_STRUCTURE)) { PIN_PROPERTIES_STRUCTURE *caps = (PIN_PROPERTIES_STRUCTURE *)rbuf; if (caps->wLcdLayout > 0) { sc_debug(ctx, "Reader has a display: %04X", caps->wLcdLayout); @@ -989,7 +984,7 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) } else sc_debug(ctx, "Reader does not have a display."); } else { - sc_debug(ctx, "Returned PIN properties structure has bad length (%d)", rcount); + sc_debug(ctx, "Returned PIN properties structure has bad length (%d/%d)", rcount, sizeof(PIN_PROPERTIES_STRUCTURE)); } } } From 6fd22203113a3d82728588e9ebc4b9e67cc25a20 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 20 Sep 2009 10:57:11 +0000 Subject: [PATCH 21/57] Bump the version number git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3742 c6295689-39f2-0310-b995-f0e70906c6a9 --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 0cd60b8e..7d30cbaa 100644 --- a/configure.ac +++ b/configure.ac @@ -3,9 +3,9 @@ dnl -*- mode: m4; -*- AC_PREREQ(2.60) define([PACKAGE_VERSION_MAJOR], [0]) -define([PACKAGE_VERSION_MINOR], [11]) -define([PACKAGE_VERSION_FIX], [9]) -define([PACKAGE_SUFFIX], [-svn]) +define([PACKAGE_VERSION_MINOR], [12]) +define([PACKAGE_VERSION_FIX], [0]) +define([PACKAGE_SUFFIX], [-svn-mp]) AC_INIT([opensc],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX]) AC_CONFIG_AUX_DIR([.]) From 9a95a40e813b4e7fcff970762d1d2485766c0c63 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 25 Sep 2009 19:29:38 +0000 Subject: [PATCH 22/57] =?UTF-8?q?Implement=20pinpad=20support=20as=20used?= =?UTF-8?q?=20by=20Portugal=20eID,=20by=20Jo=C3=A3o=20Poupino?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3744 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/opensc.h | 5 +++-- src/libopensc/reader-pcsc.c | 13 +++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 6c105a84..111fa73b 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -318,8 +318,9 @@ typedef struct sc_reader { #define SC_PIN_CMD_CHANGE 1 #define SC_PIN_CMD_UNBLOCK 2 -#define SC_PIN_CMD_USE_PINPAD 0x0001 -#define SC_PIN_CMD_NEED_PADDING 0x0002 +#define SC_PIN_CMD_USE_PINPAD 0x0001 +#define SC_PIN_CMD_NEED_PADDING 0x0002 +#define SC_PIN_CMD_IMPLICIT_CHANGE 0x0004 #define SC_PIN_ENCODING_ASCII 0 #define SC_PIN_ENCODING_BCD 1 diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index d5ac73fb..7d467b31 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -1204,11 +1204,20 @@ static int part10_build_modify_pin_block(u8 * buf, size_t * size, sc_slot_info_t tmp16 = (data->pin1.min_length << 8 ) + data->pin1.max_length; pin_modify->wPINMaxExtraDigit = HOST_TO_CCID_16(tmp16); /* Min Max */ - pin_modify->bConfirmPIN = 0x03; /* bConfirmPIN, all */ + /* bConfirmPIN flags + * 0x01: New Pin, Confirm Pin + * 0x03: Enter Old Pin, New Pin, Confirm Pin + */ + pin_modify->bConfirmPIN = data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? 0x01 : 0x03; pin_modify->bEntryValidationCondition = 0x02; /* bEntryValidationCondition, keypress only */ + /* bNumberMessage flags + * 0x02: Messages seen on Pinpad display: New Pin, Confirm Pin + * 0x03: Messages seen on Pinpad display: Enter Old Pin, New Pin, Confirm Pin + * Could be 0xFF too. + */ if (slot->capabilities & SC_SLOT_CAP_DISPLAY) - pin_modify->bNumberMessage = 0x03; /* 3 messages (because bConfirmPIN = 3), all default. Could be 0xFF too */ + pin_modify->bNumberMessage = data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? 0x02 : 0x03; else pin_modify->bNumberMessage = 0x00; /* No messages */ From 9da39d84629fe22492989b640fc9f7fcc30bb4fc Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 3 Oct 2009 07:48:28 +0000 Subject: [PATCH 23/57] Merged r3719:3749 from trunk git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3750 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/Makefile.am | 2 +- src/libopensc/Makefile.mak | 2 +- src/libopensc/card-entersafe.c | 15 +- src/libopensc/card-myeid.c | 981 +++++++++++++++++++++++++++++++++ src/libopensc/card-rtecp.c | 1 + src/libopensc/cardctl.h | 37 ++ src/libopensc/cards.h | 5 + src/libopensc/ctx.c | 1 + src/pkcs15init/Makefile.am | 5 +- src/pkcs15init/Makefile.mak | 1 + src/pkcs15init/keycache.c | 4 + src/pkcs15init/myeid.profile | 53 ++ src/pkcs15init/pkcs15-init.h | 1 + src/pkcs15init/pkcs15-lib.c | 1 + src/pkcs15init/pkcs15-myeid.c | 426 ++++++++++++++ src/scconf/README.scconf | 20 +- 16 files changed, 1534 insertions(+), 21 deletions(-) create mode 100644 src/libopensc/card-myeid.c create mode 100644 src/pkcs15init/myeid.profile create mode 100644 src/pkcs15init/pkcs15-myeid.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 01af7503..9b89cc1a 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -40,7 +40,7 @@ libopensc_la_SOURCES = \ card-oberthur.c card-belpic.c card-atrust-acos.c card-entersafe.c \ card-incrypto34.c card-piv.c card-muscle.c card-acos5.c \ card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ - card-rtecp.c card-westcos.c \ + card-rtecp.c card-westcos.c card-myeid.c \ \ pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \ pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \ diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 9ec97f16..343bcb35 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -29,7 +29,7 @@ OBJECTS = \ card-oberthur.obj card-belpic.obj card-atrust-acos.obj card-entersafe.obj \ card-incrypto34.obj card-piv.obj card-muscle.obj card-acos5.obj \ card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \ - card-rtecp.obj \ + card-rtecp.obj card-myeid.obj \ \ p15emu-westcos.obj \ pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \ diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 49c872d4..96455c8d 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -169,7 +169,6 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 *buff, size_t buffsize) { EVP_CIPHER_CTX ctx; - int i,r; u8 iv[8]={0}; SC_FUNC_CALLED(card->ctx, 1); @@ -223,7 +222,7 @@ static int entersafe_mac_apdu(sc_card_t *card, sc_apdu_t *apdu, { int r; u8 iv[8]; - u8 *tmp=0,*tmp_rounded; + u8 *tmp=0,*tmp_rounded=NULL; size_t tmpsize=0,tmpsize_rounded=0,outl=0; EVP_CIPHER_CTX ctx; @@ -430,8 +429,6 @@ static int entersafe_process_fci(struct sc_card *card, struct sc_file *file, const u8 *buf, size_t buflen) { int r; - const u8 *tag = NULL, *p = buf; - size_t taglen, len = buflen; assert(file); SC_FUNC_CALLED(card->ctx, 1); @@ -493,7 +490,7 @@ static int entersafe_select_aid(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out) { - int r; + int r = 0; if (card->cache_valid && card->cache.current_path.type == SC_PATH_TYPE_DF_NAME @@ -772,7 +769,6 @@ static int entersafe_create_file(sc_card_t *card, sc_file_t *file) SC_FUNC_CALLED(card->ctx, 1); if (file->type == SC_FILE_TYPE_WORKING_EF) { - int r; sc_entersafe_create_data data; memset(&data,0,sizeof(data)); @@ -1127,7 +1123,6 @@ static int entersafe_write_rsa_key_factor(sc_card_t *card, { int r; sc_apdu_t apdu; - u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]; SC_FUNC_CALLED(card->ctx, 1); @@ -1148,6 +1143,8 @@ static int entersafe_write_rsa_key_factor(sc_card_t *card, } {/* Write 'x'; */ + u8 sbuff[SC_MAX_APDU_BUFFER_SIZE]; + sc_format_apdu(card,&apdu,SC_APDU_CASE_3_SHORT,0x46,factor,0x00); memcpy(sbuff,data.data,data.len); @@ -1378,6 +1375,7 @@ static int entersafe_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) SC_FUNC_RETURN(card->ctx,4,SC_SUCCESS); } +#if 0 static int entersafe_preinstall_rsa_1024(sc_card_t *card,u8 key_id) { u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; @@ -1440,6 +1438,7 @@ static int entersafe_preinstall_rsa_1024(sc_card_t *card,u8 key_id) SC_FUNC_RETURN(card->ctx,4,SC_SUCCESS); } +#endif static int entersafe_preinstall_rsa_2048(sc_card_t *card,u8 key_id) { @@ -1591,6 +1590,7 @@ static int entersafe_preinstall_keys(sc_card_t *card,int (*install_rsa)(sc_card_ SC_FUNC_RETURN(card->ctx,4,SC_SUCCESS); } +#if 0 static int entersafe_card_ctl_1024(sc_card_t *card, unsigned long cmd, void *ptr) { sc_entersafe_create_data * tmp = (sc_entersafe_create_data *)ptr; @@ -1621,6 +1621,7 @@ static int entersafe_card_ctl_1024(sc_card_t *card, unsigned long cmd, void *ptr return SC_ERROR_NOT_SUPPORTED; } } +#endif static int entersafe_card_ctl_2048(sc_card_t *card, unsigned long cmd, void *ptr) { diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c new file mode 100644 index 00000000..acfa68a3 --- /dev/null +++ b/src/libopensc/card-myeid.c @@ -0,0 +1,981 @@ +/* + * card-myeid.c + * + * Copyright (C) 2008-2009 Aventra Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "internal.h" +#include "asn1.h" +#include "types.h" +#include "cardctl.h" +#include +#include + + +static enum LOAD_KEY { + LOAD_KEY_MODULUS = 0x80, + LOAD_KEY_PUBLIC_EXPONENT = 0x81, + LOAD_KEY_PRIME_P = 0x83, + LOAD_KEY_PRIME_Q = 0x84, + LOAD_KEY_DP1 = 0x85, + LOAD_KEY_DQ1 = 0x86, + LOAD_KEY_INVQ = 0x87 +}; + +static struct sc_card_operations myeid_ops; +static struct sc_card_driver myeid_drv = { + "MyEID cards with PKCS#15 applet", + "myeid", + &myeid_ops +}; + +static const char *myeid_atrs[] = { + "3B:F5:18:00:FF:81:31:FE:45:4D:79:45:49:44:65", + "3B:F5:18:00:00:81:31:FE:45:4D:79:45:49:44:9A", + NULL +}; + + +static int myeid_finish(struct sc_card *card) +{ + return 0; +} + +static int myeid_match_card(struct sc_card *card) +{ + int i, match = -1; + + for (i = 0; myeid_atrs[i] != NULL; i++) + { + u8 defatr[SC_MAX_ATR_SIZE]; + size_t len = sizeof(defatr); + const char *atrp = myeid_atrs[i]; + + if (sc_hex_to_bin(atrp, defatr, &len)) continue; + if (len != card->atr_len) + continue; + if (memcmp(card->atr, defatr, len) != 0) + continue; + match = i; + break; + } + if (match == -1) + return 0; + + return 1; +} + +static int myeid_init(struct sc_card *card) +{ + unsigned long flags =0; + + flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1; + flags |= SC_ALGORITHM_RSA_HASH_NONE | SC_ALGORITHM_RSA_HASH_SHA1; + + _sc_card_add_rsa_alg(card, 1024, flags, 0); + _sc_card_add_rsa_alg(card, 2048, flags, 0); + + /* State that we have an RNG */ + card->caps |= SC_CARD_CAP_RNG; + + return 0; +} + +static const struct sc_card_operations *iso_ops = NULL; + +static int acl_to_byte(const struct sc_acl_entry *e) +{ + switch (e->method) { + case SC_AC_NONE: + return 0x00; + case SC_AC_CHV: + case SC_AC_TERM: + case SC_AC_AUT: + if (e->key_ref == SC_AC_KEY_REF_NONE) + return -1; + if (e->key_ref < 1 || e->key_ref > 14) + return -1; + return e->key_ref; + case SC_AC_NEVER: + return 0x0F; + } + return 0x00; +} + +static void add_acl_entry(struct sc_file *file, int op, u8 byte) +{ + unsigned int method, key_ref = SC_AC_KEY_REF_NONE; + + switch (byte) + { + case 0: + method = SC_AC_NONE; + break; + case 15: + method = SC_AC_NEVER; + break; + default: + method = SC_AC_CHV; + key_ref = byte; + break; + } + sc_file_add_acl_entry(file, op, method, key_ref); +} + +static void parse_sec_attr(struct sc_file *file, const u8 *buf, size_t len) +{ + int i; + const int df_ops[4] = + { SC_AC_OP_CREATE, SC_AC_OP_CREATE, SC_AC_OP_DELETE, -1 }; + const int ef_ops[4] = + { SC_AC_OP_READ, SC_AC_OP_UPDATE, SC_AC_OP_DELETE, -1 }; + const int key_ops[4] = + { SC_AC_OP_CRYPTO, SC_AC_OP_UPDATE, SC_AC_OP_DELETE, SC_AC_OP_CRYPTO }; + + const int *ops; + + if (len < 2) + return; + + switch (file->type) { + case SC_FILE_TYPE_WORKING_EF: + ops = ef_ops; + break; + case SC_FILE_TYPE_INTERNAL_EF: + ops = key_ops; + break; + case SC_FILE_TYPE_DF: + ops = df_ops; + break; + default: + ops = key_ops; + break; + } + + for (i = 0; i < 4; i++) + { + if (ops[i] == -1) + continue; + if ((i & 1) == 0) + add_acl_entry(file, ops[i], (u8)(buf[i / 2] >> 4)); + else + add_acl_entry(file, ops[i], (u8)(buf[i / 2] & 0x0F)); + } +} + +static int myeid_select_file(struct sc_card *card, const struct sc_path *in_path, + struct sc_file **file) +{ + int r; + + r = iso_ops->select_file(card, in_path, file); + if (r) + return r; + + if (file != NULL) { + parse_sec_attr(*file, (*file)->sec_attr, (*file)->sec_attr_len); + } + + return 0; +} + +static int myeid_read_binary(struct sc_card *card, unsigned int idx, + u8 * buf, size_t count, unsigned long flags) +{ + return iso_ops->read_binary(card, idx, buf, count, flags); +} + +static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen) +{ + struct sc_apdu apdu; + int r,i; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0xA1); + apdu.resp = buf; + apdu.resplen = buflen; + apdu.le = buflen > 256 ? 256 : buflen; + + r = sc_transmit_apdu(card, &apdu); + + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu.resplen == 0) + return sc_check_sw(card, apdu.sw1, apdu.sw2); + return apdu.resplen; +} + +static int myeid_process_fci(struct sc_card *card, struct sc_file *file, + const u8 *buf, size_t buflen) +{ + size_t taglen = 0; + const u8 *tag = NULL; + int r ; + + r = iso_ops->process_fci(card, file, buf, buflen); + if (r < 0) + return r; + + if(file->type == SC_FILE_EF_UNKNOWN) + { + tag = sc_asn1_find_tag(NULL, buf, buflen, 0x82, &taglen); + if (tag != NULL && taglen > 0 && *tag == 17) + { + file->type = SC_FILE_TYPE_INTERNAL_EF; + } + } + + return 0; +} + +static int encode_file_structure(sc_card_t *card, const sc_file_t *file, + u8 *out, size_t *outlen) +{ + u8 buf[40]; + int i; + + /* PrivateKey + * 0E0000019 6217 81020400 820111 83024B01 8603000000 85028000 8A0100 RESULT 6984 + * 6217 81020400 820111 83024B01 8603000000 85021000 8A0100 */ + memset(buf,0x0,sizeof(buf)); + + buf[0] = 0x62; + buf[1] = 0x17; + /* File size */ + buf[2] = (SC_FILE_TYPE_WORKING_EF == file->type ?0x80:0x81); + buf[3] = 0x02; + buf[4] = (file->size >> 8) & 0xFF; + buf[5] = file->size & 0xFF; + + /* File Description tag */ + buf[6] = 0x82; + buf[7] = 0x01; + buf[8] = 0x01; + + /* File Identifier tag */ + buf[9] = 0x83; + buf[10] = 0x02; + buf[11] = (file->id >> 8) & 0xFF; + buf[12] = file->id & 0xFF; + + /* Security Attributes Tag */ + buf[13] = 0x86; + buf[14] = 0x03; + buf[15] = 0x0; + buf[16] = 0x0; + buf[17] = 0x0; + + if (file->sec_attr_len == 3 && file->sec_attr) + { + buf[15] = file->sec_attr[0]; + buf[16] = file->sec_attr[1]; + buf[17] = file->sec_attr[2]; + } + + /* Proprietary Information */ + buf[18] = 0x85; + buf[19] = 0x02; + /* AC right to clear default 0 */ + buf[20] = (SC_FILE_TYPE_INTERNAL_EF == file->type ?0x0:0x80); + buf[21] = 0x0; + + /* Life Cycle Status tag */ + buf[22] = 0x8A; + buf[23] = 0x01; + buf[24] = 0x0; /* RFU */ + + switch (file->type) + { + case SC_FILE_TYPE_WORKING_EF: + break; + + case SC_FILE_TYPE_INTERNAL_EF: + buf[8] = 0x11; + break; + + case SC_FILE_TYPE_DF: + buf[8] = 0x38; + if(file->namelen > 0 && file->namelen <= 16) + { + buf[25] = 0x84; + buf[26] = (u8)file->namelen; + for(i=0;i < (int)file->namelen;i++) + { + buf[i + 26] = file->name[i]; + } + buf[1] = 0x19 + file->namelen + 2; + } + break; + default: + sc_debug(card->ctx, "Unknown file type\n"); + return SC_ERROR_INVALID_ARGUMENTS; + } + + *outlen = buf[1]+2; + memcpy(out, buf, *outlen); + + return 0; +} + +static int myeid_create_file(struct sc_card *card, struct sc_file *file) +{ + sc_apdu_t apdu; + u8 sbuf[32]; + size_t buflen; + int r; + + r = encode_file_structure(card, file, sbuf, &buflen); + if (r) + return r; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00); + apdu.data = sbuf; + apdu.datalen = buflen; + apdu.lc = buflen; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu.sw1 == 0x6A && apdu.sw2 == 0x89) + return SC_ERROR_FILE_ALREADY_EXISTS; + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_TEST_RET(card->ctx, r, "Card returned error"); + + return 0; +} + +/* no record oriented file services */ +static int myeid_read_record_unsupp(struct sc_card *card, unsigned int rec_nr, + u8 *buf, size_t count, unsigned long flags) +{ + return SC_ERROR_NOT_SUPPORTED; +} + +static int myeid_wrupd_record_unsupp(struct sc_card *card, unsigned int rec_nr, + const u8 *buf, size_t count, unsigned long flags) +{ + return SC_ERROR_NOT_SUPPORTED; +} + +static int myeid_append_record_unsupp(struct sc_card *card, const u8 *buf, + size_t count, unsigned long flags) +{ + return SC_ERROR_NOT_SUPPORTED; +} + + +static int myeid_write_binary(struct sc_card *card, unsigned int idx, + const u8 *buf, size_t count, unsigned long flags) +{ + return iso_ops->write_binary(card, idx, buf, count, flags); +} + + +static int myeid_update_binary(struct sc_card *card, unsigned int idx, + const u8 *buf, size_t count, unsigned long flags) +{ + return iso_ops->update_binary(card, idx, buf, count, flags); +} + +static int myeid_delete_file(struct sc_card *card, const struct sc_path *path) +{ + int r; + struct sc_apdu apdu; + + SC_FUNC_CALLED(card->ctx, 1); + if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) + { + sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n"); + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); + } + r = sc_select_file(card, path, NULL); + SC_TEST_RET(card->ctx, r, "Unable to select file to be deleted"); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0xE4, 0x00, 0x00); + apdu.cla = 0xA0; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + return sc_check_sw(card, apdu.sw1, apdu.sw2); +} + + +static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env, + int se_num) +{ + sc_apdu_t apdu; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 *p; + int r, locked = 0; + + assert(card != NULL && env != NULL); + + + if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) + { + sc_debug(card->ctx, "asymmetric keyref not supported.\n"); + return SC_ERROR_NOT_SUPPORTED; + } + if (se_num > 0) + { + sc_debug(card->ctx, "restore security environment not supported.\n"); + return SC_ERROR_NOT_SUPPORTED; + } + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); + switch (env->operation) + { + case SC_SEC_OPERATION_DECIPHER: + apdu.p1 = 0x41; + apdu.p2 = 0xB8; + break; + case SC_SEC_OPERATION_SIGN: + apdu.p1 = 0x41; + apdu.p2 = 0xB6; + break; + default: + return SC_ERROR_INVALID_ARGUMENTS; + } + apdu.le = 0; + p = sbuf; + if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) + { + *p++ = 0x80; /* algorithm reference */ + *p++ = 0x01; + *p++ = env->algorithm_ref & 0xFF; + } + if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) + { + *p++ = 0x81; + *p++ = 2; + memcpy(p, env->file_ref.value, 2); + p += 2; + } + if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) + { + *p++ = 0x84; + *p++ = 1; + *p++ = 0; + } + r = p - sbuf; + apdu.lc = r; + apdu.datalen = r; + apdu.data = sbuf; + apdu.resplen = 0; + if (se_num > 0) { + r = sc_lock(card); + SC_TEST_RET(card->ctx, r, "sc_lock() failed"); + locked = 1; + } + if (apdu.datalen != 0) + { + r = sc_transmit_apdu(card, &apdu); + if (r) + { + sc_perror(card->ctx, r, "APDU transmit failed"); + goto err; + } + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + { + sc_perror(card->ctx, r, "Card returned error"); + goto err; + } + } + if (se_num <= 0) + return 0; + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num); + r = sc_transmit_apdu(card, &apdu); + sc_unlock(card); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + return sc_check_sw(card, apdu.sw1, apdu.sw2); +err: + if (locked) + sc_unlock(card); + return r; +} + +static int myeid_set_security_env(struct sc_card *card, + const struct sc_security_env *env, int se_num) +{ + if (env->flags & SC_SEC_ENV_ALG_PRESENT) + { + sc_security_env_t tmp; + + tmp = *env; + tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT; + tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT; + if (tmp.algorithm != SC_ALGORITHM_RSA) + { + sc_debug(card->ctx, "Only RSA algorithm supported.\n"); + return SC_ERROR_NOT_SUPPORTED; + } + + tmp.algorithm_ref = 0x00; + /* potential FIXME: return an error, if an unsupported + * pad or hash was requested, although this shouldn't happen */ + if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) + tmp.algorithm_ref = 0x02; + if (tmp.algorithm_flags & SC_ALGORITHM_RSA_HASH_SHA1) + tmp.algorithm_ref |= 0x10; + return myeid_set_security_env2(card, &tmp, se_num); + } + return myeid_set_security_env2(card, env, se_num); +} + +static int myeid_compute_signature(struct sc_card *card, const u8 * data, + size_t datalen, u8 * out, size_t outlen) +{ + int r; + struct sc_apdu apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + + assert(card != NULL && data != NULL && out != NULL); + if (datalen > 256) + SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS); + + /* INS: 0x2A PERFORM SECURITY OPERATION + * P1: 0x9E Resp: Digital Signature + * P2: 0x9A Cmd: Input for Digital Signature */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + if (datalen == 256) + { + apdu.p2 = data[0]; + memcpy(sbuf, data+1, datalen-1); + apdu.lc = datalen - 1; + apdu.datalen = datalen - 1; + } + else + { + memcpy(sbuf, data, datalen); + apdu.lc = datalen; + apdu.datalen = datalen; + } + + apdu.data = sbuf; + apdu.sensitive = 1; + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + int len = apdu.resplen > outlen ? outlen : apdu.resplen; + + memcpy(out, apdu.resp, len); + SC_FUNC_RETURN(card->ctx, 4, len); + } + + SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, apdu.sw2)); +} + +static int myeid_decipher(struct sc_card *card, const u8 * crgram, + size_t crgram_len, u8 * out, size_t outlen) +{ + int r; + struct sc_apdu apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + + assert(card != NULL && crgram != NULL && out != NULL); + SC_FUNC_CALLED(card->ctx, 2); + if (crgram_len > 256) + SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS); + + /* INS: 0x2A PERFORM SECURITY OPERATION + * P1: 0x80 Resp: Plain value + * P2: 0x86 Cmd: Padding indicator byte followed by cryptogram */ + sc_format_apdu(card, &apdu, + (crgram_len < 256) ? SC_APDU_CASE_4_SHORT : SC_APDU_CASE_3_SHORT, + 0x2A, 0x80, 0x86); + + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = crgram_len; + apdu.sensitive = 1; + + if (crgram_len == 256) + { apdu.le = 0; + /* padding indicator byte, 0x81 = first half of 2048 bit cryptogram */ + sbuf[0] = 0x81; + memcpy(sbuf + 1, crgram, crgram_len / 2); + apdu.lc = crgram_len / 2 + 1; + } + else + { + sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ + memcpy(sbuf + 1, crgram, crgram_len); + apdu.lc = crgram_len + 1; + } + + apdu.datalen = apdu.lc; apdu.data = sbuf; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + if (crgram_len == 256) + { + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, + 0x2A, 0x80, 0x86); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = crgram_len; + apdu.sensitive = 1; + /* padding indicator byte, + * 0x82 = Second half of 2048 bit cryptogram */ + sbuf[0] = 0x82; + memcpy(sbuf + 1, crgram + crgram_len / 2, crgram_len / 2); + apdu.lc = crgram_len / 2 + 1; + apdu.datalen = apdu.lc; + apdu.data = sbuf; + + r = sc_transmit_apdu(card, &apdu); + + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) + { + int len = apdu.resplen > outlen ? outlen : apdu.resplen; + memcpy(out, apdu.resp, len); + SC_FUNC_RETURN(card->ctx, 2, len); + } + } + else + { + int len = apdu.resplen > outlen ? outlen : apdu.resplen; + + memcpy(out, apdu.resp, len); + SC_FUNC_RETURN(card->ctx, 2, len); + } + } + SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2)); +} + +/* Write internal data, e.g. add default pin-records to pin */ +static int myeid_putdata(struct sc_card *card, struct sc_cardctl_myeid_data_obj* data_obj) +{ + int r; + struct sc_apdu apdu; + + SC_FUNC_CALLED(card->ctx, 1); + + memset(&apdu, 0, sizeof(apdu)); + apdu.cse = SC_APDU_CASE_3_SHORT; + apdu.cla = 0x00; + apdu.ins = 0xDA; + apdu.p1 = data_obj->P1; + apdu.p2 = data_obj->P2; + apdu.lc = data_obj->DataLen; + apdu.datalen = data_obj->DataLen; + apdu.data = data_obj->Data; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_TEST_RET(card->ctx, r, "PUT_DATA returned error"); + + SC_FUNC_RETURN(card->ctx, 1, r); +} + +/* Read internal data, e.g. get RSA public key */ +static int myeid_getdata(struct sc_card *card, struct sc_cardctl_myeid_data_obj* data_obj) +{ + int r; + struct sc_apdu apdu; + + SC_FUNC_CALLED(card->ctx, 1); + + memset(&apdu, 0, sizeof(apdu)); + apdu.cse = SC_APDU_CASE_2_SHORT; + apdu.cla = 0x00; + apdu.ins = 0xCA; /* GET DATA */ + apdu.p1 = data_obj->P1; + apdu.p2 = data_obj->P2; + apdu.lc = 0; + apdu.datalen = 0; + apdu.data = data_obj->Data; + + apdu.le = 256; + apdu.resp = data_obj->Data; + apdu.resplen = data_obj->DataLen; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_TEST_RET(card->ctx, r, "GET_DATA returned error"); + + if (apdu.resplen > data_obj->DataLen) + r = SC_ERROR_WRONG_LENGTH; + else + data_obj->DataLen = apdu.resplen; + + SC_FUNC_RETURN(card->ctx, 1, r); +} + +static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) +{ + sc_apdu_t apdu; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + int r, len; + + len = 0; + if(value_len == 0 || value == NULL) + return 0; + + if(value != NULL && + value[0] != 0x0 && + mode != LOAD_KEY_PUBLIC_EXPONENT) + sbuf[len++] = 0x0; + + SC_FUNC_CALLED(card->ctx, 1); + + if(mode == LOAD_KEY_MODULUS && value_len >= 256) + { + r=0; + if((value_len % 2) > 0 && value[0] == 0x00) + { + value_len--; + memmove(value, value + 1, value_len); + } + mode = 0x88; + len = 128; + memcpy(sbuf,value, 128); + + memset(&apdu, 0, sizeof(apdu)); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode); + + apdu.cla = 0x00; + apdu.data = sbuf; + apdu.datalen = len; + apdu.lc = len; + + r = sc_transmit_apdu(card, &apdu); + if(r < 0) + return r; + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if(r < 0) + return r; + + mode = 0x89; + len = value_len - 128; + memset(&sbuf, 0, SC_MAX_APDU_BUFFER_SIZE); + memcpy(sbuf,value + 128, value_len - 128); + } + else + { + memcpy(sbuf + len, value, value_len); + len += value_len; + } + + memset(&apdu, 0, sizeof(apdu)); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDA, 0x01, mode); + + apdu.cla = 0x00; + apdu.data = sbuf; + apdu.datalen = len; + apdu.lc = len; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_FUNC_RETURN(card->ctx, 1, r); + +} + +/* Generate or store a key */ +static int myeid_generate_store_key(struct sc_card *card, + struct sc_cardctl_myeid_gen_store_key_info *data) +{ + struct sc_apdu apdu; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + int r,len; + + /* Setup key-generation paramters */ + if (data->op_type == OP_TYPE_GENERATE) + { + len = 0; + + sbuf[len++] = 0x30; + sbuf[len++] = 0x05; + sbuf[len++] = 0x81; + sbuf[len++] = data->pubexp_len; + + memcpy(sbuf + len, data->pubexp, data->pubexp_len); + len += data->pubexp_len; + + memset(&apdu, 0, sizeof(apdu)); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x46, 0x00, 0x00); + apdu.cla = 0x00; + apdu.data = sbuf; + apdu.datalen = len; + apdu.lc = len; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_TEST_RET(card->ctx, r, "GENERATE_KEY returned error"); + + SC_FUNC_RETURN(card->ctx, 1, r); + } + else + { + if((r=myeid_loadkey(card, LOAD_KEY_PRIME_P, + data->primep, data->primep_len)) >= 0 && + (r=myeid_loadkey(card, LOAD_KEY_PRIME_Q, + data->primeq, data->primeq_len)) >= 0 && + (r=myeid_loadkey(card, LOAD_KEY_DP1, + data->dp1, data->dp1_len)) >= 0 && + (r=myeid_loadkey(card, LOAD_KEY_DQ1, + data->dq1, data->dq1_len)) >= 0 && + (r=myeid_loadkey(card, LOAD_KEY_INVQ, + data->invq, data->invq_len)) >= 0 && + (r=myeid_loadkey(card, LOAD_KEY_MODULUS, + data->mod, data->mod_len)) >= 0 && + (r=myeid_loadkey(card, LOAD_KEY_PUBLIC_EXPONENT, + data->pubexp, data->pubexp_len)) >= 0) + return r; + } + + return r; +} + +static int myeid_activate_card(struct sc_card *card) +{ + int r; + u8 sbuf[] ="\xA0\x00\x00\x00\x63\x50\x4B\x43\x53\x2D\x31\x35"; + sc_apdu_t apdu; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x44, 0x04, 0x00); + apdu.cla = 0x00; + apdu.data = sbuf; + apdu.datalen = 0x0C; + apdu.lc = 0x0C; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_TEST_RET(card->ctx, r, "ACTIVATE_APPLET returned error"); + + SC_FUNC_RETURN(card->ctx, 1, r); +} + +static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) +{ + int r; + sc_apdu_t apdu; + u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0xA0); + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + + 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 (apdu.resplen != 20) + { + sc_debug(card->ctx, "unexpected response to GET DATA serial number\n"); + return SC_ERROR_INTERNAL; + } + + /* cache serial number */ + memcpy(card->serialnr.value, &rbuf[10], 8); + card->serialnr.len = 8; + + /* copy and return serial number */ + memcpy(serial, &card->serialnr, sizeof(*serial)); + + return SC_SUCCESS; +} + +static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) +{ + switch(cmd) { + case SC_CARDCTL_MYEID_PUTDATA: + return myeid_putdata(card, + (struct sc_cardctl_myeid_data_obj*) ptr); + case SC_CARDCTL_MYEID_GETDATA: + return myeid_getdata(card, + (struct sc_cardctl_myeid_data_obj*) ptr); + case SC_CARDCTL_MYEID_GENERATE_KEY: + return myeid_generate_store_key(card, + (struct sc_cardctl_myeid_gen_store_key_info *) ptr); + case SC_CARDCTL_MYEID_ACTIVATE_CARD: + return myeid_activate_card(card); + case SC_CARDCTL_GET_SERIALNR: + return myeid_get_serialnr(card, (sc_serial_number_t *)ptr); + } + + return SC_ERROR_NOT_SUPPORTED; +} + +/* "The PINs are "global" in a PKCS#15 sense, meaning that they remain valid + * until card reset! Selecting another applet doesn't invalidate the PINs, + * you need to reset the card." - javacard@zurich.ibm.com, when asked about + * how to invalidate logged in pins. +*/ +static int myeid_logout(struct sc_card *card) +{ + return 0; /* Can't */ +} + +static struct sc_card_driver * sc_get_driver(void) +{ + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); + + myeid_ops = *iso_drv->ops; + myeid_ops.match_card = myeid_match_card; + myeid_ops.init = myeid_init; + myeid_ops.finish = myeid_finish; + if (iso_ops == NULL) + iso_ops = iso_drv->ops; + myeid_ops.read_binary = myeid_read_binary; + myeid_ops.read_record = myeid_read_record_unsupp; + myeid_ops.write_record = myeid_wrupd_record_unsupp; + myeid_ops.append_record = myeid_append_record_unsupp; + myeid_ops.update_record = myeid_wrupd_record_unsupp; + myeid_ops.write_binary = myeid_write_binary; + myeid_ops.update_binary = myeid_update_binary; + myeid_ops.select_file = myeid_select_file; + myeid_ops.create_file = myeid_create_file; + myeid_ops.delete_file = myeid_delete_file; + myeid_ops.list_files = myeid_list_files; + myeid_ops.set_security_env = myeid_set_security_env; + myeid_ops.compute_signature = myeid_compute_signature; + myeid_ops.decipher = myeid_decipher; + myeid_ops.logout = myeid_logout; + myeid_ops.process_fci = myeid_process_fci; + myeid_ops.card_ctl = myeid_card_ctl; + + return &myeid_drv; +} + +struct sc_card_driver * sc_get_myeid_driver(void) +{ + return sc_get_driver(); +} + diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 79ada5af..65d66495 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -639,6 +639,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) apdu.resp = buf; apdu.resplen = sizeof(buf); apdu.le = sizeof(buf) - 2; + serial->len = sizeof(serial->value); break; case SC_CARDCTL_RTECP_GENERATE_KEY: if (!genkey_data) diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 657fa185..409c89b9 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -188,6 +188,14 @@ enum { SC_CARDCTL_WESTCOS_SET_DEFAULT_KEY, SC_CARDCTL_WESTCOS_LOAD_DATA, + /* + * MyEID specific calls + */ + SC_CARDCTL_MYEID_BASE = _CTL_PREFIX('M', 'Y', 'E'), + SC_CARDCTL_MYEID_PUTDATA, + SC_CARDCTL_MYEID_GETDATA, + SC_CARDCTL_MYEID_GENERATE_KEY, + SC_CARDCTL_MYEID_ACTIVATE_CARD, }; enum { @@ -690,6 +698,35 @@ typedef struct sc_rtecp_genkey_data { size_t modulus_len; } sc_rtecp_genkey_data_t; +/* +* MyEID stuff +*/ + struct sc_cardctl_myeid_data_obj { + int P1; + int P2; + u8 * Data; + size_t DataLen; + int LengthMax; + }; + + struct sc_cardctl_myeid_gen_store_key_info { + int op_type; + unsigned int mod_len; + unsigned char *mod; + unsigned int pubexp_len; + unsigned char *pubexp; + unsigned int primep_len; + unsigned char *primep; + unsigned int primeq_len; + unsigned char *primeq; + unsigned int dp1_len; + unsigned char *dp1; + unsigned int dq1_len; + unsigned char *dq1; + unsigned int invq_len; + unsigned char *invq; +}; + #ifdef __cplusplus } #endif diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 465059ba..c1778d2f 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -146,6 +146,10 @@ enum { SC_CARD_TYPE_ENTERSAFE_BASE = 19000, SC_CARD_TYPE_ENTERSAFE_3K, SC_CARD_TYPE_ENTERSAFE_FTCOS_PK_01C, + + /* MyEID cards */ + SC_CARD_TYPE_MYEID_BASE = 20000, + SC_CARD_TYPE_MYEID_GENERIC, }; extern sc_card_driver_t *sc_get_default_driver(void); @@ -175,6 +179,7 @@ extern sc_card_driver_t *sc_get_entersafe_driver(void); extern sc_card_driver_t *sc_get_rutoken_driver(void); extern sc_card_driver_t *sc_get_rtecp_driver(void); extern sc_card_driver_t *sc_get_westcos_driver(void); +extern sc_card_driver_t *sc_get_myeid_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index efde1157..e9832b17 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -85,6 +85,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "rutoken", (void *(*)(void)) sc_get_rutoken_driver }, { "rutoken_ecp",(void *(*)(void)) sc_get_rtecp_driver }, { "westcos", (void *(*)(void)) sc_get_westcos_driver }, + { "myeid", (void *(*)(void)) sc_get_myeid_driver }, /* emv is not really implemented */ { "emv", (void *(*)(void)) sc_get_emv_driver }, /* The default driver should be last, as it handles all the diff --git a/src/pkcs15init/Makefile.am b/src/pkcs15init/Makefile.am index 7f41e86f..bd0ee28f 100644 --- a/src/pkcs15init/Makefile.am +++ b/src/pkcs15init/Makefile.am @@ -25,7 +25,8 @@ dist_pkgdata_DATA = \ asepcos.profile \ entersafe.profile \ rutoken_ecp.profile \ - westcos.profile + westcos.profile \ + myeid.profile AM_CPPFLAGS = -DSC_PKCS15_PROFILE_DIRECTORY=\"$(pkgdatadir)\" AM_CFLAGS = $(OPTIONAL_OPENSSL_CFLAGS) $(LTLIB_CFLAGS) @@ -38,7 +39,7 @@ libpkcs15init_la_SOURCES = \ pkcs15-cardos.c pkcs15-jcop.c pkcs15-starcos.c \ pkcs15-oberthur.c pkcs15-setcos.c pkcs15-incrypto34.c \ pkcs15-muscle.c pkcs15-asepcos.c pkcs15-rutoken.c \ - pkcs15-entersafe.c pkcs15-rtecp.c \ + pkcs15-entersafe.c pkcs15-rtecp.c pkcs15-myeid.c \ pkcs15init.exports if WIN32 libpkcs15init_la_SOURCES += versioninfo.rc diff --git a/src/pkcs15init/Makefile.mak b/src/pkcs15init/Makefile.mak index ca23a37f..60f45d47 100644 --- a/src/pkcs15init/Makefile.mak +++ b/src/pkcs15init/Makefile.mak @@ -11,6 +11,7 @@ OBJECTS = pkcs15-lib.obj profile.obj keycache.obj \ pkcs15-oberthur.obj pkcs15-setcos.obj pkcs15-incrypto34.obj \ pkcs15-muscle.obj pkcs15-asepcos.obj pkcs15-rutoken.obj \ pkcs15-entersafe.obj pkcs15-rtecp.obj pkcs15-westcos.obj \ + pkcs15-myeid.obj \ versioninfo.res all: install-headers $(TARGET) diff --git a/src/pkcs15init/keycache.c b/src/pkcs15init/keycache.c index 017042eb..4c8eb135 100644 --- a/src/pkcs15init/keycache.c +++ b/src/pkcs15init/keycache.c @@ -264,6 +264,10 @@ sc_keycache_set_pin_name(const sc_path_t *path, int ref, int name) s = new_entry(path, SC_AC_CHV, ref); if (s == NULL) return SC_ERROR_OUT_OF_MEMORY; + + s->len = sc_keycache_get_key(path, SC_AC_CHV, -1, s->value, MAX_SECRET); + if(s->len < 0) + return SC_ERROR_OBJECT_NOT_FOUND; } /* Set the pin name */ diff --git a/src/pkcs15init/myeid.profile b/src/pkcs15init/myeid.profile new file mode 100644 index 00000000..063553d5 --- /dev/null +++ b/src/pkcs15init/myeid.profile @@ -0,0 +1,53 @@ +# +# PKCS15 r/w profile for MyEID cards +# +cardinfo { + max-pin-length = 8; + pin-encoding = ascii-numeric; + pin-pad-char = 0x00; +} + +# Define reasonable limits for PINs and PUK +# Note that we do not set a file path or reference +# here; that is done dynamically. +PIN user-pin { + attempts = 3; +} +PIN user-puk { + attempts = 10; +} + +# Additional filesystem info. +# This is added to the file system info specified in the +# main profile. +filesystem { + DF MF { + DF PKCS15-AppDF { + EF template-private-key { + type = internal-ef; + file-id = 4B01; # This is the base FileID + size = 266; # 266 is enough for 1024-bit keys + ACL = *=NEVER, CRYPTO=$PIN, UPDATE=$PIN; + } + EF template-public-key { + file-id = 5501; + ACL = *=NEVER, READ=NONE, UPDATE=$PIN; + } + EF template-certificate { + file-id = 4301; + ACL = *=NEVER, READ=NONE, UPDATE=$PIN; + } + EF template-extractable-key { + file-id = 7000; + ACL = *=NEVER, READ=$PIN, UPDATE=$PIN; + } + } + } +} + +# Define an SO pin +# This PIN is not used yet. +#PIN sopin { +# file = sopinfile; +# reference = 0; +#} diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 8c37a186..2319d1a4 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -405,6 +405,7 @@ extern struct sc_pkcs15init_operations *sc_pkcs15init_get_rutoken_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_entersafe_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_rtecp_ops(void); extern struct sc_pkcs15init_operations *sc_pkcs15init_get_westcos_ops(void); +extern struct sc_pkcs15init_operations *sc_pkcs15init_get_myeid_ops(void); #ifdef __cplusplus } diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 8322a631..87e3f53f 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -166,6 +166,7 @@ static struct profile_operations { { "entersafe",(void*) sc_pkcs15init_get_entersafe_ops }, { "rutoken_ecp", (void *) sc_pkcs15init_get_rtecp_ops }, { "westcos", (void *) sc_pkcs15init_get_westcos_ops }, + { "myeid", (void *) sc_pkcs15init_get_myeid_ops }, { NULL, NULL }, }; diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c new file mode 100644 index 00000000..83f39ef1 --- /dev/null +++ b/src/pkcs15init/pkcs15-myeid.c @@ -0,0 +1,426 @@ +/* + * MyEID specific operations for PKCS15 initialization + * + * Copyright (C) 2008-2009 Aventra Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include "pkcs15-init.h" +#include "keycache.h" +#include "profile.h" + +#define MYEID_MAX_PINS 5 + +unsigned char MYEID_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01}; +#define MYEID_DEFAULT_PUBKEY_LEN sizeof(MYEID_DEFAULT_PUBKEY) + +static int myeid_generate_store_key( sc_profile_t *, sc_card_t *, + unsigned int, unsigned int, sc_pkcs15_pubkey_t *, + sc_pkcs15_prkey_t *, sc_pkcs15_prkey_info_t *); + +static int myeid_create_pin_internal(sc_profile_t *, sc_card_t *, + int, sc_pkcs15_pin_info_t *, const u8 *, size_t, + const u8 *, size_t); + +static int myeid_puk_retries(sc_profile_t *, int); + +/* + * Erase the card. + */ +static int myeid_erase_card(sc_profile_t *profile, sc_card_t *card) +{ + struct sc_cardctl_myeid_data_obj data_obj; + sc_pkcs15_pin_info_t pin_info; + u8 data[8]; + int r; + + /* Just delete the entire MF */ + + /* The SO pin has pin reference 1 -- not that it matters much + * because pkcs15-init will ask to enter all pins, even if we + * did a --so-pin on the command line. */ + sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info); + sc_keycache_set_pin_name(NULL, pin_info.reference, SC_PKCS15INIT_SO_PIN); + + /* Select parent DF and verify PINs/key as necessary */ + r = sc_pkcs15init_authenticate(profile, card, profile->mf_info->file, SC_AC_OP_DELETE); + if (r < 0) + return r == SC_ERROR_FILE_NOT_FOUND ? 0 : r; + + data[0]= 0xFF; + data[1]= 0xFF; + data[2]= 0x33; + data[3]= 0x3F; + data[4]= 0xFF; + data[5]= 0x33; + data[6]= 0x3F; + data[7]= 0xFF; + + data_obj.P1 = 0x01; + data_obj.P2 = 0xE0; + data_obj.Data = data; + data_obj.DataLen = 0x08; + + r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); + + return r; +} + +/* + * Select the PIN reference + */ +static int myeid_select_pin_reference(sc_profile_t *profile, sc_card_t *card, + sc_pkcs15_pin_info_t *pin_info) +{ + sc_pkcs15_pin_info_t pin_info_prof; + + pin_info_prof.reference = 1; /* Default SO PIN ref. */ + sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info_prof); + + /* For the SO pin, we take the first available pin reference = 1 */ + if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) + pin_info->reference = pin_info_prof.reference; + /* sc_pkcs15init_create_pin() starts checking if 0 is an acceptable + * pin reference, which isn't for the myeid cards. And since the + * value 1 has been assigned to the SO pin, we'll jump to 2. */ + else if (pin_info->reference == 0) + pin_info->reference = pin_info_prof.reference + 1; + + return 0; +} + +/* + * Create a new PIN + */ +static int myeid_create_pin(sc_profile_t *profile, sc_card_t *card, + sc_file_t *df, sc_pkcs15_object_t *pin_obj, + const u8 *pin, size_t pin_len, + const u8 *puk, size_t puk_len) +{ + return myeid_create_pin_internal(profile, card, + 0, (sc_pkcs15_pin_info_t *) pin_obj->data, + pin, pin_len, + puk, puk_len); +} + +/* + * Setup file struct & path: get correct template from the profile, construct full path + * num = number of objects of this type already on the card + */ +static int myeid_new_file(sc_profile_t *profile, sc_card_t *card, + unsigned int type, unsigned int num, + sc_file_t **out) +{ + sc_file_t *file; + sc_path_t *p; + char name[64], *tag; + int r; + + if (type == SC_PKCS15_TYPE_PRKEY_RSA) + tag = "private-key"; + else if (type == SC_PKCS15_TYPE_PUBKEY_RSA) + tag = "public-key"; + else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_CERT) + tag = "certificate"; + else if ((type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT) + tag = "data"; + else + { + sc_debug(card->ctx, "Unsupported file type"); + return SC_ERROR_INVALID_ARGUMENTS; + } + + /* Get template from profile */ + snprintf(name, sizeof(name), "template-%s", tag); + if (sc_profile_get_file(profile, name, &file) < 0) + { + sc_debug(card->ctx, "Profile doesn't define %s", name); + return SC_ERROR_NOT_SUPPORTED; + } + + /* Auto-increment FID for next object */ + file->id += num; + p = &file->path; + *p = profile->df_info->file->path; + p->value[p->len++] = (u8) (file->id / 256); + p->value[p->len++] = (u8) (file->id % 256); + + /* Increment FID until there's no file with such path */ + r = sc_select_file(card, p, NULL); + while(r == 0) + { + file->id++; + p->value[p->len - 2] = (u8) (file->id / 256); + p->value[p->len - 1] = (u8) (file->id % 256); + r = sc_select_file(card, p, NULL); + } + + *out = file; + return 0; +} + +static int myeid_encode_private_key(sc_profile_t *profile, sc_card_t *card, + struct sc_pkcs15_prkey_rsa *rsa, u8 *key, + size_t *keysize, int key_ref) +{ + return 0; +} + +static int myeid_encode_public_key(sc_profile_t *profile, sc_card_t *card, + struct sc_pkcs15_prkey_rsa *rsa, u8 *key, + size_t *keysize, int key_ref) +{ + return 0; +} + +/* + * Generate RSA key + */ +static int myeid_generate_key(sc_profile_t *profile, sc_card_t *card, + unsigned int index, /* keyref: 0 for 1st key, ... */ + unsigned int keybits, + sc_pkcs15_pubkey_t *pubkey, + struct sc_pkcs15_prkey_info *info) +{ + return myeid_generate_store_key(profile, card, index, keybits, + pubkey, NULL, info); +} + +/* + * Store RSA key + */ +static int myeid_new_key(sc_profile_t *profile, sc_card_t *card, + struct sc_pkcs15_prkey *key, unsigned int index, + struct sc_pkcs15_prkey_info *info) +{ + return myeid_generate_store_key(profile, card, index, + key->u.rsa.modulus.len * 8, NULL, key, info); +} + +/* + * Common code for generating or storing a private key. + * If pubkey == NULL and prkey != NULL, we have to store a private key + * In the oposite case, we have to generate a private key + */ +static int myeid_generate_store_key(sc_profile_t *profile, sc_card_t *card, + unsigned int index, /* keynumber: 0 for 1st priv key, ... */ + unsigned int keybits, + sc_pkcs15_pubkey_t *pubkey, + sc_pkcs15_prkey_t *prkey, + sc_pkcs15_prkey_info_t *info) +{ + struct sc_cardctl_myeid_gen_store_key_info args; + struct sc_cardctl_myeid_data_obj data_obj; + unsigned char raw_pubkey[256]; + int r; + unsigned int mod_len; + sc_file_t *prkf = NULL; + + /* Parameter check */ + if ( (keybits < 1024) || (keybits > 2048) || (keybits & 0X7)) { + sc_debug(card->ctx, + "Unsupported key size [%u]: 1024-2048 bit + 8-multiple\n", keybits); + return SC_ERROR_INVALID_ARGUMENTS; + } + + /* Get the private key file */ + r = myeid_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, index, &prkf); + if (r < 0) + goto done; + + /* Take enough room for a 1024 bit key */ + if (prkf->size < 1024) + prkf->size = 1024; + + /* Now create the key file */ + r = sc_pkcs15init_create_file(profile, card, prkf); + if (r < 0) + goto done; + + /* Fill in data structure */ + memset(&args, 0, sizeof(args)); + args.mod_len = keybits; + if (prkey == NULL) + { + args.op_type = OP_TYPE_GENERATE; + args.pubexp_len = MYEID_DEFAULT_PUBKEY_LEN; + args.pubexp = MYEID_DEFAULT_PUBKEY; + } + else + { + args.op_type = OP_TYPE_STORE; + args.pubexp_len = prkey->u.rsa.exponent.len; + args.pubexp = prkey->u.rsa.exponent.data; + args.primep_len = prkey->u.rsa.p.len; + args.primep = prkey->u.rsa.p.data; + args.primeq_len = prkey->u.rsa.q.len; + args.primeq = prkey->u.rsa.q.data; + + args.dp1_len = prkey->u.rsa.dmp1.len; + args.dp1 = prkey->u.rsa.dmp1.data; + args.dq1_len = prkey->u.rsa.dmq1.len; + args.dq1 = prkey->u.rsa.dmq1.data; + args.invq_len = prkey->u.rsa.iqmp.len; + args.invq = prkey->u.rsa.iqmp.data; + + args.mod_len = prkey->u.rsa.modulus.len; + args.mod = prkey->u.rsa.modulus.data; + } + + /* Authenticate */ + r = sc_pkcs15init_authenticate(profile, card, prkf, SC_AC_OP_UPDATE); + if (r < 0) + goto done; + + /* Generate/store rsa key */ + r = sc_card_ctl(card, SC_CARDCTL_MYEID_GENERATE_KEY, &args); + if (r < 0) + goto done; + + info->key_reference = 0; + info->path = prkf->path; + +done: + if (prkf) + sc_file_free(prkf); + + return r; +} + +/* + * Create a new PIN + */ +static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card, + int ignore_ac, sc_pkcs15_pin_info_t *pin_info, + const u8 *pin, size_t pin_len, + const u8 *puk, size_t puk_len) +{ + u8 data[19]; + int so_pin_ref; + int r; + struct sc_cardctl_myeid_data_obj data_obj; + sc_file_t *pinfile = NULL; + + if (pin_info->reference >= MYEID_MAX_PINS) + return SC_ERROR_INVALID_ARGUMENTS; + if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4) + return SC_ERROR_INVALID_PIN_LENGTH; + + /* Verify required access rights if needed (i.e. if the + * pin file isn't in the CREATE life cycle state). */ + if (!ignore_ac) + { + /* Re-ink the SO pin to the MF because there is the pin file */ + so_pin_ref = sc_keycache_find_named_pin(&profile->df_info->file->path, + SC_PKCS15INIT_SO_PIN); + if (so_pin_ref >= 0) + sc_keycache_set_pin_name(&profile->mf_info->file->path, + so_pin_ref, SC_PKCS15INIT_SO_PIN); + + r = sc_profile_get_file(profile, "pinfile", &pinfile); + if (r >= 0) + r = sc_pkcs15init_authenticate(profile, card, pinfile, SC_AC_OP_UPDATE); + sc_file_free(pinfile); + if (r < 0) + return r; + } + + /* Make command to add a pin-record */ + data_obj.P1 = 01; + data_obj.P2 = pin_info->reference; /* myeid pin number */ + + memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin*/ + memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */ + + + /* Optional PIN locking + * data[17] = pin_info->tries_left & 0x0F; + * data[18] = myeid_puk_retries(profile, pin_info->reference) & 0x0F; + */ + + data[17] = 0x00; + data[18] = 0x00; + data[19] = 0x00; + + data_obj.Data = data; + data_obj.DataLen = 0x10; + + r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); + + return r; +} + +static int myeid_puk_retries(sc_profile_t *profile, int pin_ref) +{ + sc_pkcs15_pin_info_t pin_info; + + pin_info.reference = 1; /* Default SO PIN ref. */ + sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info); + + /* If pin_ref is the SO PIN, get the SO PUK info, otherwise the User PUK info */ + sc_profile_get_pin_info(profile, + pin_ref == pin_info.reference ? + SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, + &pin_info); + + if ((pin_info.tries_left < 0) || (pin_info.tries_left > 15)) + return 3; /* Little extra safety */ + return pin_info.tries_left; +} + +/* For Myeid, all objects are files that can be deleted in any order */ +static int myeid_delete_object(struct sc_profile *profile, + struct sc_card *card, unsigned int type, + const void *data, const sc_path_t *path) +{ + return sc_pkcs15init_delete_by_path(profile, card, path); +} + +static struct sc_pkcs15init_operations sc_pkcs15init_myeid_operations = { + myeid_erase_card, + NULL, /* init_card */ + NULL, /* create_dir */ + NULL, /* create_domain */ + myeid_select_pin_reference, + myeid_create_pin, + NULL, /* select_key_reference */ + NULL, /* create_key */ + NULL, /* store_key */ + NULL, /* generate_key */ + myeid_encode_private_key, + myeid_encode_public_key, + NULL, /* finalize_card */ + NULL, + NULL, /* style api */ + myeid_new_key, + myeid_new_file, + myeid_generate_key, + myeid_delete_object +}; + +struct sc_pkcs15init_operations *sc_pkcs15init_get_myeid_ops(void) +{ + return &sc_pkcs15init_myeid_operations; +} diff --git a/src/scconf/README.scconf b/src/scconf/README.scconf index 5ce86fb7..f30e3823 100644 --- a/src/scconf/README.scconf +++ b/src/scconf/README.scconf @@ -18,7 +18,7 @@ It isn't It doesn't have - anything else but data. No locking, no threads etc. -It has heirarchical data blocks, it has lists. +It has heirarchical data blocks, it has lists. Similar, but different: - .ini files. scconf is block structured, has lists and arrays @@ -216,8 +216,8 @@ typedef struct _scconf_entry { * Look for blocks with this key, or check if this * block has an item with this key. Run the block * or blocks found against the rest of this entry - * Stop after the first one, unless - * SCCONF_ALL_BLOCKS is set in flags + * Stop after the first one, unless + * SCCONF_ALL_BLOCKS is set in flags unsigned int type; * SCCONF_CALLBACK * parm contains a function ptr of type @@ -226,7 +226,7 @@ typedef struct _scconf_entry { * scconf_entry* entry, * int depth); * run the callback with the block found - * + * * SCCONF_BLOCK * param contains a pointer to another entry table * use the found block against every entry @@ -269,7 +269,7 @@ typedef struct _scconf_entry { * where a pointer to a copy of list * can be stored * - * + * unsigned int flags; * SCCONF_PRESENT * This bit is or'ed in when found @@ -298,8 +298,8 @@ Sub-blocks can be added, and callbacks can be issued. This is a handy method for adding scconf data from within a program. typedef struct _scconf_entry { - const char *name; - * key value for blocks and items * + const char *name; + * key value for blocks and items * unsigned int type; * SCCONF_CALLBACK * parm contains a function ptr of type @@ -307,12 +307,12 @@ typedef struct _scconf_entry { * scconf_block* block, * scconf_entry* entry, * int depth); - * + * * SCCONF_BLOCK * param contains a pointer to another entry table * the entry table is added as a block to the * current block, with name as the key, and - * arg is a list of names + * arg is a list of names * * SCCONF_LIST * SCCONF_BOOLEAN @@ -320,7 +320,7 @@ typedef struct _scconf_entry { * SCCONF_STRING * these add key=value pairs to the current * block. The value is in parm. - * + * unsigned int flags; * SCCONF_PRESENT * This bit is or'ed in when item added From 64f95782020f6305810a4550fc33762377dfab16 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 3 Oct 2009 09:31:07 +0000 Subject: [PATCH 24/57] apdu.sensitive is not in use since [2868] git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3751 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-akis.c | 1 - src/libopensc/card-asepcos.c | 4 ---- src/libopensc/card-atrust-acos.c | 2 -- src/libopensc/card-cardos.c | 1 - src/libopensc/card-entersafe.c | 1 - src/libopensc/card-flex.c | 3 --- src/libopensc/card-gemsafeV1.c | 3 --- src/libopensc/card-gpk.c | 4 ---- src/libopensc/card-incrypto34.c | 1 - src/libopensc/card-jcop.c | 2 -- src/libopensc/card-mcrd.c | 2 -- src/libopensc/card-myeid.c | 3 --- src/libopensc/card-oberthur.c | 5 ----- src/libopensc/card-rtecp.c | 3 --- src/libopensc/card-starcos.c | 1 - src/libopensc/card-westcos.c | 1 - src/libopensc/iso7816.c | 3 --- src/libopensc/types.h | 3 --- 18 files changed, 43 deletions(-) diff --git a/src/libopensc/card-akis.c b/src/libopensc/card-akis.c index 3aa0548c..af92c77f 100644 --- a/src/libopensc/card-akis.c +++ b/src/libopensc/card-akis.c @@ -354,7 +354,6 @@ akis_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left p1 = 1; } sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, p1, p2); - apdu.sensitive = 1; buf[0] = data->pin1.len; memcpy(buf+1, data->pin1.data, data->pin1.len); diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index ead84585..317639f1 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -509,7 +509,6 @@ static int asepcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_le * to tell the card the we want everything available (note: we * always have Le <= crgram_len) */ apdu.le = (outlen >= 256 && crgram_len < 256) ? 256 : outlen; - apdu.sensitive = 1; apdu.data = crgram; apdu.lc = crgram_len; @@ -990,9 +989,6 @@ static int asepcos_build_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, default: return SC_ERROR_NOT_SUPPORTED; } - /* all PIN related APDUs are sensitive */ - apdu->sensitive = 1; - return SC_SUCCESS; } diff --git a/src/libopensc/card-atrust-acos.c b/src/libopensc/card-atrust-acos.c index e19991ae..2922eafd 100644 --- a/src/libopensc/card-atrust-acos.c +++ b/src/libopensc/card-atrust-acos.c @@ -706,7 +706,6 @@ static int atrust_acos_compute_signature(struct sc_card *card, apdu.lc = 0; apdu.datalen = 0; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { @@ -781,7 +780,6 @@ static int atrust_acos_decipher(struct sc_card *card, sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); - apdu.sensitive = 1; sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ memcpy(sbuf + 1, crgram, crgram_len); diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index b6f0924e..7a225dee 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -774,7 +774,6 @@ do_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, apdu.data = data; apdu.lc = datalen; apdu.datalen = datalen; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 96455c8d..92a1d792 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -907,7 +907,6 @@ static int entersafe_compute_with_prkey(sc_card_t *card, apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = 256; - apdu.sensitive = 1; r = entersafe_transmit_apdu(card, &apdu,0,0,0,0); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); diff --git a/src/libopensc/card-flex.c b/src/libopensc/card-flex.c index 2a932b2d..acdb6241 100644 --- a/src/libopensc/card-flex.c +++ b/src/libopensc/card-flex.c @@ -1066,7 +1066,6 @@ cryptoflex_compute_signature(sc_card_t *card, const u8 *data, apdu.resplen = outlen > sizeof(sbuf) ? sizeof(sbuf) : outlen; apdu.le = apdu.resplen > 256 ? 256 : apdu.resplen; apdu.resp = sbuf; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -1106,7 +1105,6 @@ cyberflex_compute_signature(sc_card_t *card, const u8 *data, apdu.data = data; apdu.resplen = outlen; apdu.resp = out; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); @@ -1279,7 +1277,6 @@ static int flex_build_verify_apdu(sc_card_t *card, sc_apdu_t *apdu, apdu->data = sbuf; apdu->datalen = len; apdu->lc = len; - apdu->sensitive = 1; return 0; } diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index d0ef7a22..c562f2de 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -429,7 +429,6 @@ static int gemsafe_compute_signature(struct sc_card *card, const u8 * data, apdu.data = sbuf; apdu.lc = data_len + 2; apdu.datalen = data_len + 2; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -459,7 +458,6 @@ static int gemsafe_decipher(struct sc_card *card, const u8 * crgram, apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = crgram_len; - apdu.sensitive = 1; apdu.data = crgram; apdu.lc = crgram_len; @@ -549,7 +547,6 @@ static int gemsafe_build_pin_apdu(struct sc_card *card, apdu->datalen = len; apdu->data = sbuf; apdu->resplen = 0; - apdu->sensitive = 1; return 0; } diff --git a/src/libopensc/card-gpk.c b/src/libopensc/card-gpk.c index 7a80fb72..602f137b 100644 --- a/src/libopensc/card-gpk.c +++ b/src/libopensc/card-gpk.c @@ -994,7 +994,6 @@ gpk_select_key(sc_card_t *card, int key_sfi, const u8 *buf, size_t buflen) apdu.resp = resp; apdu.resplen = sizeof(resp); apdu.le = 12; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -1347,7 +1346,6 @@ gpk_decipher(sc_card_t *card, const u8 *in, size_t inlen, apdu.le = 256; /* give me all you got :) */ apdu.resp = buffer; apdu.resplen = sizeof(buffer); - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -1582,7 +1580,6 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args) apdu.p1 = args->file->id & 0x1F; apdu.p2 = args->len; apdu.lc = args->datalen; - apdu.sensitive = 1; /* encrypt the private key material */ assert(args->datalen <= sizeof(temp)); @@ -1836,7 +1833,6 @@ gpk_build_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, struct sc_pin_cmd_data *dat apdu->lc = 8; apdu->datalen = 8; apdu->data = sbuf; - apdu->sensitive = 1; return 0; } diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index 65812bd6..15685d03 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -516,7 +516,6 @@ static int do_compute_signature(sc_card_t *card, apdu.data = sbuf; apdu.lc = datalen; apdu.datalen = datalen; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); diff --git a/src/libopensc/card-jcop.c b/src/libopensc/card-jcop.c index 8aa47559..e52ec699 100644 --- a/src/libopensc/card-jcop.c +++ b/src/libopensc/card-jcop.c @@ -751,7 +751,6 @@ static int jcop_compute_signature(sc_card_t *card, } apdu.data = sbuf; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { @@ -789,7 +788,6 @@ static int jcop_decipher(sc_card_t *card, apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); /* FIXME */ apdu.le = crgram_len; - apdu.sensitive = 1; if (crgram_len == 256) { apdu.p2 = crgram[0]; diff --git a/src/libopensc/card-mcrd.c b/src/libopensc/card-mcrd.c index 95b59250..3cbca6f3 100644 --- a/src/libopensc/card-mcrd.c +++ b/src/libopensc/card-mcrd.c @@ -1311,8 +1311,6 @@ static int mcrd_decipher(sc_card_t * card, apdu.datalen = crgram_len; apdu.lc = apdu.datalen; - apdu.sensitive = 1; - r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); r = sc_check_sw(card, apdu.sw1, apdu.sw2); diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index acfa68a3..162a7327 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -568,7 +568,6 @@ static int myeid_compute_signature(struct sc_card *card, const u8 * data, } apdu.data = sbuf; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -606,7 +605,6 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = crgram_len; - apdu.sensitive = 1; if (crgram_len == 256) { apdu.le = 0; @@ -635,7 +633,6 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); apdu.le = crgram_len; - apdu.sensitive = 1; /* padding indicator byte, * 0x82 = Second half of 2048 bit cryptogram */ sbuf[0] = 0x82; diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 03283f39..79471989 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -1462,7 +1462,6 @@ auth_update_component(sc_card_t *card, struct auth_update_component_info *args) apdu.data = sbuf; apdu.datalen = len; apdu.lc = len; - apdu.sensitive = 1; if (args->len == 0x100) { sbuf[0] = args->type; sbuf[1] = 0x20; @@ -1724,7 +1723,6 @@ auth_verify(sc_card_t *card, unsigned int type, apdu.data = sbuf; apdu.datalen = pinfo.pad_length; apdu.lc = pinfo.pad_length; - apdu.sensitive = 1; } else { sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0, pin_ref); @@ -1776,7 +1774,6 @@ auth_change_reference_data (sc_card_t *card, unsigned int type, apdu.data = sbuf; apdu.datalen = pinfo.pad_length * 2; apdu.lc = pinfo.pad_length * 2; - apdu.sensitive = 1; rv = sc_transmit_apdu(card, &apdu); sc_mem_clear(sbuf, sizeof(sbuf)); @@ -1842,7 +1839,6 @@ auth_reset_retry_counter(sc_card_t *card, unsigned int type, apdu.data = sbuf; apdu.datalen = len; apdu.lc = len; - apdu.sensitive = 1; rv = sc_transmit_apdu(card, &apdu); sc_mem_clear(sbuf, sizeof(sbuf)); @@ -1905,7 +1901,6 @@ auth_create_reference_data (sc_card_t *card, apdu.data = sbuf; apdu.datalen = len; apdu.lc = len; - apdu.sensitive = 1; rv = sc_transmit_apdu(card, &apdu); sc_mem_clear(sbuf, sizeof(sbuf)); diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 65d66495..550e8da3 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -337,7 +337,6 @@ static int rtecp_verify(sc_card_t *card, unsigned int type, int ref_qualifier, apdu.lc = data_len; apdu.data = data; apdu.datalen = data_len; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (send_logout++ == 0 && apdu.sw1 == 0x6F && apdu.sw2 == 0x86) @@ -403,7 +402,6 @@ static int rtecp_rsa_cipher(sc_card_t *card, const u8 *data, size_t data_len, apdu.lc = data_len; apdu.data = buf; apdu.datalen = data_len; - apdu.sensitive = 1; apdu.resp = buf_out; apdu.resplen = data_len + 2; apdu.le = data_len; @@ -513,7 +511,6 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type, apdu.lc = p - buf; apdu.data = buf; apdu.datalen = p - buf; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); sc_mem_clear(buf, sizeof(buf)); diff --git a/src/libopensc/card-starcos.c b/src/libopensc/card-starcos.c index ea943d7c..d4d79f3a 100644 --- a/src/libopensc/card-starcos.c +++ b/src/libopensc/card-starcos.c @@ -1181,7 +1181,6 @@ static int starcos_compute_signature(sc_card_t *card, apdu.lc = 0; apdu.datalen = 0; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 68abf48d..40d2b722 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -885,7 +885,6 @@ static int westcos_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, apdu.datalen = len; apdu.data = buf; apdu.resplen = 0; - apdu.sensitive = 1; if (!use_pin_pad) { /* Transmit the APDU to the card */ diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c index 4c1e64ff..7863240a 100644 --- a/src/libopensc/iso7816.c +++ b/src/libopensc/iso7816.c @@ -782,7 +782,6 @@ static int iso7816_compute_signature(sc_card_t *card, apdu.data = sbuf; apdu.lc = datalen; apdu.datalen = datalen; - apdu.sensitive = 1; r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { @@ -819,7 +818,6 @@ static int iso7816_decipher(sc_card_t *card, * to tell the card the we want everything available (note: we * always have Le <= crgram_len) */ apdu.le = (outlen >= 256 && crgram_len < 256) ? 256 : outlen; - apdu.sensitive = 1; sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */ memcpy(sbuf + 1, crgram, crgram_len); @@ -908,7 +906,6 @@ static int iso7816_build_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, apdu->datalen = len; apdu->data = buf; apdu->resplen = 0; - apdu->sensitive = 1; return 0; } diff --git a/src/libopensc/types.h b/src/libopensc/types.h index 5aeb9677..94016ccf 100644 --- a/src/libopensc/types.h +++ b/src/libopensc/types.h @@ -113,9 +113,6 @@ typedef struct sc_apdu { u8 *resp; /* R-APDU data buffer */ size_t resplen; /* in: size of R-APDU buffer, * out: length of data returned in R-APDU */ - u8 sensitive; /* Set if either the command or - * the response contains secrets, - * e.g. a PIN. */ u8 control; /* Set if APDU should go to the reader */ unsigned int sw1, sw2; /* Status words returned in R-APDU */ From ab2ed07b78f09af05b06ab566355e4482a5bace3 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 3 Oct 2009 10:06:53 +0000 Subject: [PATCH 25/57] Fix APDU sanity check. By Emanuele Pucciarelli, http://itacns.corp.it/hg/itacns/file/adc0b2ceec86/patches/010-apdu.patch git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3752 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/apdu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index 663b7c1e..ebd09c5e 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -300,15 +300,15 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) goto error; break; case SC_APDU_CASE_3_SHORT: + /* inconsistent datalen */ + if (apdu->datalen != apdu->lc) + goto error; /* data is send */ - if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0) + if (apdu->datalen != 0 && apdu->data == NULL) goto error; /* no data is expected */ if (apdu->le != 0) goto error; - /* inconsistent datalen */ - if (apdu->datalen != apdu->lc) - goto error; break; case SC_APDU_CASE_4_SHORT: /* data is send */ From 99e84ae82a4f32518cf5f91d81f8a512654c9a35 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 3 Oct 2009 10:07:55 +0000 Subject: [PATCH 26/57] Fix spelling git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3753 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/apdu.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index ebd09c5e..e63e207a 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -284,12 +284,12 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) switch (apdu->cse & SC_APDU_SHORT_MASK) { case SC_APDU_CASE_1: - /* no data is send or received */ + /* no data is sent or received */ if (apdu->datalen != 0 || apdu->lc != 0 || apdu->le != 0) goto error; break; case SC_APDU_CASE_2_SHORT: - /* no data is send */ + /* no data is sent */ if (apdu->datalen != 0 || apdu->lc != 0) goto error; /* data is expected */ @@ -303,7 +303,7 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) /* inconsistent datalen */ if (apdu->datalen != apdu->lc) goto error; - /* data is send */ + /* data is sent */ if (apdu->datalen != 0 && apdu->data == NULL) goto error; /* no data is expected */ @@ -311,7 +311,7 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) goto error; break; case SC_APDU_CASE_4_SHORT: - /* data is send */ + /* data is sent */ if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0) goto error; /* data is expected */ @@ -366,7 +366,7 @@ static void sc_detect_apdu_cse(const sc_card_t *card, sc_apdu_t *apdu) /** Sends a single APDU to the card reader and calls * GET RESPONSE to get the return data if necessary. * @param card sc_card_t object for the smartcard - * @param apdu APDU to be send + * @param apdu APDU to be sent * @return SC_SUCCESS on success and an error value otherwise */ static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu) From a8dc97e0dc19ff538edfda89d2184c393bdc0318 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 3 Oct 2009 10:13:45 +0000 Subject: [PATCH 27/57] Cardos security env patch for Italian CNI card. By Emanuele Pucciarelli, http://itacns.corp.it/hg/itacns/file/adc0b2ceec86/patches/115-cardos-secenv.patch git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3754 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-cardos.c | 16 +++++++++++++--- src/libopensc/cards.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 7a225dee..1ca70753 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -42,7 +42,7 @@ static struct sc_atr_table cardos_atrs[] = { /* 4.0 */ { "3b:e2:00:ff:c1:10:31:fe:55:c8:02:9c", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL }, /* Italian eID card, postecert */ - { "3b:e9:00:ff:c1:10:31:fe:55:00:64:05:00:c8:02:31:80:00:47", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL }, + { "3b:e9:00:ff:c1:10:31:fe:55:00:64:05:00:c8:02:31:80:00:47", NULL, NULL, SC_CARD_TYPE_CARDOS_CIE_V1, 0, NULL }, /* Italian eID card, infocamere */ { "3b:fb:98:00:ff:c1:10:31:fe:55:00:64:05:20:47:03:31:80:00:90:00:f3", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL }, /* Another Italian InfocamereCard */ @@ -65,6 +65,9 @@ static int cardos_match_card(sc_card_t *card) i = _sc_match_atr(card, cardos_atrs, &card->type); if (i < 0) return 0; + /* Do not change card type for CIE! */ + if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1) + return 1; if (card->type == SC_CARD_TYPE_CARDOS_M4_2) { int rv; sc_apdu_t apdu; @@ -685,7 +688,8 @@ cardos_restore_security_env(sc_card_t *card, int se_num) SC_FUNC_CALLED(card->ctx, 1); - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 3, se_num); + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0, se_num); + apdu.p1 = (card->type == SC_CARD_TYPE_CARDOS_CIE_V1 ? 0xF3 : 0x03); r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); @@ -724,7 +728,13 @@ cardos_set_security_env(sc_card_t *card, } key_id = env->key_ref[0]; - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 1, 0); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0); + if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1) { + cardos_restore_security_env(card, 0x30); + apdu.p1 = 0xF1; + } else { + apdu.p1 = 0x01; + } switch (env->operation) { case SC_SEC_OPERATION_DECIPHER: apdu.p2 = 0xB8; diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index c1778d2f..05f32e1e 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -44,6 +44,7 @@ enum { SC_CARD_TYPE_CARDOS_M4_3, SC_CARD_TYPE_CARDOS_M4_2B, /* 4.2b is after 4.3b */ SC_CARD_TYPE_CARDOS_M4_2C, + SC_CARD_TYPE_CARDOS_CIE_V1, /* Italian CIE (eID) v1 */ /* flex/cyberflex drivers */ SC_CARD_TYPE_FLEX_BASE = 2000, From 9c7eb8122afb1653d4b1bfe27a5c5b1bf9ced211 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 3 Oct 2009 14:41:14 +0000 Subject: [PATCH 28/57] =?UTF-8?q?Add=20support=20for=20Portugese=20eID=20o?= =?UTF-8?q?n=20IAS=20and=20Gemsafe=20cards,=20by=20Jo=C3=A3o=20Poupino.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3755 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/Makefile.am | 4 +- src/libopensc/Makefile.mak | 4 +- src/libopensc/card-gemsafeV1.c | 124 +++++--- src/libopensc/card-ias.c | 550 +++++++++++++++++++++++++++++++++ src/libopensc/cards.h | 10 + src/libopensc/ctx.c | 1 + src/libopensc/dir.c | 4 +- src/libopensc/pkcs15-pteid.c | 295 ++++++++++++++++++ src/libopensc/pkcs15-syn.c | 5 + 9 files changed, 947 insertions(+), 50 deletions(-) create mode 100644 src/libopensc/card-ias.c create mode 100644 src/libopensc/pkcs15-pteid.c diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am index 9b89cc1a..08b38256 100644 --- a/src/libopensc/Makefile.am +++ b/src/libopensc/Makefile.am @@ -40,12 +40,12 @@ libopensc_la_SOURCES = \ card-oberthur.c card-belpic.c card-atrust-acos.c card-entersafe.c \ card-incrypto34.c card-piv.c card-muscle.c card-acos5.c \ card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ - card-rtecp.c card-westcos.c card-myeid.c \ + card-rtecp.c card-westcos.c card-myeid.c card-ias.c\ \ pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \ pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \ pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ - pkcs15-esinit.c p15emu-westcos.c \ + pkcs15-esinit.c p15emu-westcos.c pkcs15-pteid.c \ compression.c p15card-helper.c \ \ libopensc.exports diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 343bcb35..43f65b1f 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -29,13 +29,13 @@ OBJECTS = \ card-oberthur.obj card-belpic.obj card-atrust-acos.obj card-entersafe.obj \ card-incrypto34.obj card-piv.obj card-muscle.obj card-acos5.obj \ card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \ - card-rtecp.obj card-myeid.obj \ + card-rtecp.obj card-myeid.obj card-ias.obj \ \ p15emu-westcos.obj \ pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \ pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \ pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ - pkcs15-esinit.obj \ + pkcs15-esinit.obj pkcs15-pteid.c \ compression.obj p15card-helper.obj \ versioninfo.res diff --git a/src/libopensc/card-gemsafeV1.c b/src/libopensc/card-gemsafeV1.c index c562f2de..352150ff 100644 --- a/src/libopensc/card-gemsafeV1.c +++ b/src/libopensc/card-gemsafeV1.c @@ -15,6 +15,7 @@ */ /* Initially written by David Mattes (david.mattes@boeing.com) */ +/* Portuguese eID card support by Joao Poupino (joao.poupino@ist.utl.pt) */ #include "internal.h" #include "cardctl.h" @@ -32,20 +33,27 @@ static struct sc_card_driver gemsafe_drv = { NULL, 0, NULL }; -static const char *gemexpresso_atrs[] = { - /* standard version */ - "3B:7B:94:00:00:80:65:B0:83:01:01:74:83:00:90:00", - "3B:6B:00:00:80:65:B0:83:01:01:74:83:00:90:00", - /* fips 140 version */ - "3B:6B:00:00:80:65:B0:83:01:03:74:83:00:90:00", - /* TODO: add more ATRs */ - "3B:7A:94:00:00:80:65:A2:01:01:01:3D:72:D6:43", - "3B:7D:94:00:00:80:31:80:65:B0:83:01:01:90:83:00:90:00", - NULL +/* Known ATRs */ +static struct sc_atr_table gemsafe_atrs[] = { + /* standard version */ + {"3B:7B:94:00:00:80:65:B0:83:01:01:74:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL}, + {"3B:6B:00:00:80:65:B0:83:01:01:74:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL}, + /* fips 140 version */ + {"3B:6B:00:00:80:65:B0:83:01:03:74:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL}, + /* Undefined */ + {"3B:7A:94:00:00:80:65:A2:01:01:01:3D:72:D6:43", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL}, + {"3B:7D:94:00:00:80:31:80:65:B0:83:01:01:90:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL}, + /* Portuguese eID cards */ + {"3B:7D:95:00:00:80:31:80:65:B0:83:11:C0:A9:83:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL}, + {"3B:7D:95:00:00:80:31:80:65:B0:83:11:C0:A9:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} }; static const u8 gemsafe_def_aid[] = {0xA0, 0x00, 0x00, 0x00, 0x18, 0x0A, 0x00, 0x00, 0x01, 0x63, 0x42, 0x00}; + +static const u8 gemsafe_pteid_aid[] = {0x60, 0x46, 0x32, 0xFF, 0x00, 0x00, 0x02}; + /* static const u8 gemsafe_def_aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50, 0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35}; @@ -113,27 +121,12 @@ static int gp_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len) return SC_SUCCESS; } -static int gemsafe_match_card(struct sc_card *card) +static int gemsafe_match_card(sc_card_t *card) { - int i, match = -1; + int i; - SC_FUNC_CALLED(card->ctx, 1); - - for (i = 0; gemexpresso_atrs[i] != NULL; i++) { - u8 defatr[SC_MAX_ATR_SIZE]; - size_t len = sizeof(defatr); - const char *atrp = gemexpresso_atrs[i]; - - if (sc_hex_to_bin(atrp, defatr, &len)) - continue; - if (len != card->atr_len) - continue; - if (memcmp(card->atr, defatr, len) != 0) - continue; - match = i + 1; - break; - } - if (match == -1) + i = _sc_match_atr(card, gemsafe_atrs, &card->type); + if (i < 0) return 0; return 1; @@ -153,12 +146,17 @@ static int gemsafe_init(struct sc_card *card) if (!exdata) return SC_ERROR_OUT_OF_MEMORY; exdata->aid_len = sizeof(exdata->aid); - /* try to get a AID from the config file */ - r = get_conf_aid(card, exdata->aid, &exdata->aid_len); - if (r < 0) { - /* failed, use default value */ - memcpy(exdata->aid, gemsafe_def_aid, sizeof(gemsafe_def_aid)); - exdata->aid_len = sizeof(gemsafe_def_aid); + if(card->type == SC_CARD_TYPE_GEMSAFEV1_GENERIC) { + /* try to get a AID from the config file */ + r = get_conf_aid(card, exdata->aid, &exdata->aid_len); + if (r < 0) { + /* failed, use default value */ + memcpy(exdata->aid, gemsafe_def_aid, sizeof(gemsafe_def_aid)); + exdata->aid_len = sizeof(gemsafe_def_aid); + } + } else if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) { + memcpy(exdata->aid, gemsafe_pteid_aid, sizeof(gemsafe_pteid_aid)); + exdata->aid_len = sizeof(gemsafe_pteid_aid); } /* increase lock_count here to prevent sc_unlock to select @@ -343,18 +341,18 @@ static int gemsafe_process_fci(struct sc_card *card, struct sc_file *file, return SC_SUCCESS; } -static u8 gemsafe_flags2algref(const struct sc_security_env *env) +static u8 gemsafe_flags2algref(struct sc_card *card, const struct sc_security_env *env) { u8 ret = 0; if (env->operation == SC_SEC_OPERATION_SIGN) { if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) - ret = 0x12; + ret = card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID ? 0x02 : 0x12; else if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_ISO9796) ret = 0x11; } else if (env->operation == SC_SEC_OPERATION_DECIPHER) { if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) - ret = 0x12; + ret = card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID ? 0x02 : 0x12; } return ret; @@ -388,7 +386,7 @@ static int gemsafe_set_security_env(struct sc_card *card, if (!(se_env.flags & SC_SEC_ENV_ALG_REF_PRESENT)) { /* set the algorithm reference */ - alg_ref = gemsafe_flags2algref(&se_env); + alg_ref = gemsafe_flags2algref(card, &se_env); if (alg_ref) { se_env.algorithm_ref = alg_ref; se_env.flags |= SC_SEC_ENV_ALG_REF_PRESENT; @@ -417,11 +415,16 @@ static int gemsafe_compute_signature(struct sc_card *card, const u8 * data, return SC_ERROR_INVALID_ARGUMENTS; } - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0xAC); - apdu.cla |= 0x80; - apdu.resp = rbuf; - apdu.resplen = sizeof(rbuf); - apdu.le = 256; + /* the Portuguese eID card requires a two-phase exchange */ + if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) { + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x90, 0xA0); + } else { + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0xAC); + apdu.cla |= 0x80; + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + apdu.le = 256; + } /* we sign a digestInfo object => tag 0x90 */ sbuf[0] = 0x90; sbuf[1] = (u8)data_len; @@ -433,6 +436,17 @@ static int gemsafe_compute_signature(struct sc_card *card, const u8 * data, r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) { + /* finalize the exchange */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x9E, 0x9A); + apdu.le = 128; /* 1024 bit keys */ + apdu.resp = rbuf; + apdu.resplen = sizeof(rbuf); + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + if(apdu.sw1 != 0x90 || apdu.sw2 != 0x00) + SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2)); + } int len = apdu.resplen > outlen ? outlen : apdu.resplen; memcpy(out, apdu.resp, len); @@ -473,6 +487,25 @@ static int gemsafe_decipher(struct sc_card *card, const u8 * crgram, SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2)); } +static int gemsafe_get_challenge(sc_card_t *card, u8 *rnd, size_t len) +{ + int prev_cla, r; + + prev_cla = card->cla; + if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) { + /* Warning: this depends on iso7816_get_challenge not + * changing the value of the card's CLA + */ + card->cla = 0x80; + } + r = iso_ops->get_challenge(card, rnd, len); + /* Restore the CLA value if needed */ + if(card->cla != prev_cla) + card->cla = prev_cla; + + return r; +} + static int gemsafe_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu, struct sc_pin_cmd_data *data) @@ -622,7 +655,7 @@ static struct sc_card_driver *sc_get_driver(void) iso_ops = iso_drv->ops; /* use the standard iso operations as default */ gemsafe_ops = *iso_drv->ops; - /* gemsafe specfic functions */ + /* gemsafe specific functions */ gemsafe_ops.match_card = gemsafe_match_card; gemsafe_ops.init = gemsafe_init; gemsafe_ops.finish = gemsafe_finish; @@ -631,6 +664,7 @@ static struct sc_card_driver *sc_get_driver(void) gemsafe_ops.set_security_env = gemsafe_set_security_env; gemsafe_ops.decipher = gemsafe_decipher; gemsafe_ops.compute_signature = gemsafe_compute_signature; + gemsafe_ops.get_challenge = gemsafe_get_challenge; gemsafe_ops.process_fci = gemsafe_process_fci; gemsafe_ops.pin_cmd = gemsafe_pin_cmd; diff --git a/src/libopensc/card-ias.c b/src/libopensc/card-ias.c new file mode 100644 index 00000000..034d92d0 --- /dev/null +++ b/src/libopensc/card-ias.c @@ -0,0 +1,550 @@ +/* + * Driver for IAS based cards, e.g. Portugal's eID card. + * + * Copyright (C) 2009, Joao Poupino + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Partially based on the ISO7816 driver. + * + * Thanks to Andre Cruz, Jorge Ferreira and Paulo F. Andrade + */ + +#include "internal.h" +#include "cardctl.h" +#include "asn1.h" +#include +#include + +/* Portugal eID uses 1024 bit keys */ +#define PTEID_RSA_KEYSIZE 128 + +#define DRVDATA(card) ((struct ias_priv_data *) ((card)->drv_data)) + +static struct sc_card_operations ias_ops; +static struct sc_card_operations *iso_ops = NULL; + +static struct sc_card_driver ias_drv = { + "IAS", + "ias", + &ias_ops, + NULL, 0, NULL +}; + +/* Known ATRs */ +static struct sc_atr_table ias_atrs[] = { + /* Portugal eID cards */ + {"3B:65:00:00:D0:00:54:01:31", NULL, NULL, SC_CARD_TYPE_IAS_PTEID, 0, NULL}, + {"3B:65:00:00:D0:00:54:01:32", NULL, NULL, SC_CARD_TYPE_IAS_PTEID, 0, NULL}, + {"3B:95:95:40:FF:D0:00:54:01:31", NULL, NULL, SC_CARD_TYPE_IAS_PTEID, 0, NULL}, + {"3B:95:95:40:FF:D0:00:54:01:32", NULL, NULL, SC_CARD_TYPE_IAS_PTEID, 0, NULL}, + {NULL, NULL, NULL, 0, 0, NULL} +}; + +/* Known AIDs */ +static const u8 ias_aid_pteid[] = {0x60, 0x46, 0x32, 0xFF, 0x00, 0x01, 0x02}; + +static int ias_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len) +{ + int r; + sc_path_t tpath; + + tpath.type = SC_PATH_TYPE_DF_NAME; + tpath.len = aid_len; + memcpy(tpath.value, aid, aid_len); + r = iso_ops->select_file(card, &tpath, NULL); + if (r != SC_SUCCESS) { + sc_debug(card->ctx, "unable to select applet"); + return r; + } + + return SC_SUCCESS; +} + +static int ias_init(sc_card_t *card) +{ + unsigned long flags; + + assert(card != NULL); + + SC_FUNC_CALLED(card->ctx, 1); + card->name = "IAS"; + card->cla = 0x00; + + /* Card version detection */ + if (card->type == SC_CARD_TYPE_IAS_PTEID) { + int r = ias_select_applet(card, ias_aid_pteid, sizeof(ias_aid_pteid)); + if (r != SC_SUCCESS) + return r; + /* Add other cards if necessary */ + } else { + return SC_ERROR_INTERNAL; + } + + /* Set card capabilities */ + card->caps |= SC_CARD_CAP_RNG; + + /* Set the supported algorithms */ + flags = SC_ALGORITHM_RSA_PAD_PKCS1 | + SC_ALGORITHM_RSA_HASH_NONE; + + /* Only 1024 bit key sizes were tested */ + _sc_card_add_rsa_alg(card, 1024, flags, 0); + + return SC_SUCCESS; +} + +static int ias_finish(sc_card_t *card) +{ + return SC_SUCCESS; +} + +static int ias_match_card(sc_card_t *card) +{ + int i; + + i = _sc_match_atr(card, ias_atrs, &card->type); + if (i < 0) + return 0; + + return 1; +} + +static int ias_build_pin_apdu(sc_card_t *card, + sc_apdu_t *apdu, + struct sc_pin_cmd_data *data) +{ + static u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + int r, len, pad, use_pin_pad, ins, p1; + + r = len = pad = use_pin_pad = ins = p1 = 0; + assert(card != NULL); + + switch (data->pin_type) { + case SC_AC_CHV: + break; + default: + return SC_ERROR_INVALID_ARGUMENTS; + } + + if (data->flags & SC_PIN_CMD_USE_PINPAD) + use_pin_pad = 1; + /* "needs-padding" necessary for the PTEID card, + * but not defined in the pin structure + */ + if ((data->flags & SC_PIN_CMD_NEED_PADDING) || + card->type == SC_CARD_TYPE_IAS_PTEID) + pad = 1; + + data->pin1.offset = 5; + + switch (data->cmd) { + case SC_PIN_CMD_VERIFY: + ins = 0x20; + if ( (r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0) + return r; + len = r; + break; + case SC_PIN_CMD_CHANGE: + ins = 0x24; + if ((data->flags & SC_PIN_CMD_IMPLICIT_CHANGE) == 0 && + (data->pin1.len != 0 || use_pin_pad)) { + if ( (r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0) + return r; + len += r; + } else { + /* implicit test */ + p1 = 1; + } + data->pin2.offset = data->pin1.offset + len; + if ( (r = sc_build_pin(sbuf+len, sizeof(sbuf)-len, &data->pin2, pad)) < 0) + return r; + len += r; + break; + case SC_PIN_CMD_UNBLOCK: + ins = 0x2C; + if (data->pin1.len != 0 || use_pin_pad) { + if ( (r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0) + return r; + len += r; + } else { + p1 |= 0x02; + } + if (data->pin2.len != 0 || use_pin_pad) { + data->pin2.offset = data->pin1.offset + len; + if ( (r = sc_build_pin(sbuf+len, sizeof(sbuf)-len, &data->pin2, pad)) < 0) + return r; + len += r; + } else { + p1 |= 0x01; + } + break; + default: + return SC_ERROR_NOT_SUPPORTED; + } + + sc_format_apdu(card, apdu, SC_APDU_CASE_3_SHORT, ins, p1, data->pin_reference); + apdu->lc = len; + apdu->datalen = len; + apdu->data = sbuf; + apdu->resplen = 0; + + return SC_SUCCESS; +} + +static int ias_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, + int *tries_left) +{ + int r; + sc_apdu_t local_apdu; + + SC_FUNC_CALLED(card->ctx, 1); + + /* Check if a PIN change operation is being requested, + * as it requires sending two separate APDUs + */ + if (data->cmd == SC_PIN_CMD_CHANGE) { + /* Build a SC_PIN_CMD_VERIFY APDU */ + data->cmd = SC_PIN_CMD_VERIFY; + r = ias_build_pin_apdu(card, &local_apdu, data); + if (r < 0) + return r; + data->apdu = &local_apdu; + r = iso_ops->pin_cmd(card, data, tries_left); + if (r < 0) + return r; + /* Continue processing */ + data->cmd = SC_PIN_CMD_CHANGE; + /* The IAS spec mandates an implicit change PIN operation */ + data->flags |= SC_PIN_CMD_IMPLICIT_CHANGE; + } + + r = ias_build_pin_apdu(card, &local_apdu, data); + if (r < 0) + return r; + data->apdu = &local_apdu; + + return iso_ops->pin_cmd(card, data, tries_left); +} + +static int ias_set_security_env(sc_card_t *card, + const sc_security_env_t *env, int se_num) +{ + int r; + sc_apdu_t apdu; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + + sc_debug(card->ctx, "ias_set_security_env, keyRef = 0x%0x, algo = 0x%0x\n", + *env->key_ref, env->algorithm_flags); + + assert(card != NULL && env != NULL); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0); + switch (env->operation) { + case SC_SEC_OPERATION_DECIPHER: + apdu.p2 = 0xB8; /* confidentiality template */ + sbuf[0] = 0x95; /* tag for usage qualifier byte */ + sbuf[1] = 0x01; /* tag length */ + sbuf[2] = 0x40; /* data decryption */ + sbuf[3] = 0x84; /* tag for private key reference */ + sbuf[4] = 0x01; /* tag length */ + sbuf[5] = *env->key_ref; /* key reference */ + sbuf[6] = 0x80; /* tag for algorithm reference */ + sbuf[7] = 0x01; /* tag length */ + if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) + sbuf[8] = 0x1A; /* RSA PKCS#1 with no data formatting */ + else { + sc_debug(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n", + env->algorithm_flags); + return SC_ERROR_INVALID_ARGUMENTS; + } + apdu.lc = 9; + apdu.datalen = 9; + break; + case SC_SEC_OPERATION_SIGN: + apdu.p2 = 0xA4; /* authentication template */ + sbuf[0] = 0x95; /* tag for usage qualifier byte */ + sbuf[1] = 0x01; /* tag length */ + sbuf[2] = 0x40; /* internal authentication */ + sbuf[3] = 0x84; /* tag for private key reference */ + sbuf[4] = 0x01; /* tag length */ + sbuf[5] = *env->key_ref; /* key reference */ + sbuf[6] = 0x80; /* tag for algorithm reference */ + sbuf[7] = 0x01; /* tag length */ + if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1) + sbuf[8] = 0x02; /* RSA PKCS#1 with no data formatting */ + else { + sc_debug(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n", + env->algorithm_flags); + return SC_ERROR_INVALID_ARGUMENTS; + } + apdu.lc = 9; + apdu.datalen = 9; + break; + default: + return SC_ERROR_INVALID_ARGUMENTS; + } + apdu.le = 0; + apdu.data = sbuf; + apdu.resplen = 0; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "Set Security Env APDU transmit failed"); + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_TEST_RET(card->ctx, r, "Card's Set Security Env command returned error"); + + return r; +} + +static int ias_compute_signature(sc_card_t *card, const u8 * data, + size_t data_len, u8 * out, size_t outlen) +{ + int r; + size_t len = 0; + sc_apdu_t apdu; + u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + sc_context_t *ctx = card->ctx; + + SC_FUNC_CALLED(ctx, 1); + + if (data_len > 64) { + sc_debug(ctx, "error: input data too long: %lu bytes\n", data_len); + return SC_ERROR_INVALID_ARGUMENTS; + } + + /* Send the data */ + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x88, 0x02, 0x00); + memcpy(sbuf, data, data_len); + apdu.data = sbuf; + apdu.lc = data_len; + apdu.datalen = data_len; + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + + /* Get the result */ + if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { + len = card->type == SC_CARD_TYPE_IAS_PTEID ? PTEID_RSA_KEYSIZE : outlen; + r = iso_ops->get_response(card, &len, out); + if (r == 0) + SC_FUNC_RETURN(card->ctx, 2, len); + else + SC_FUNC_RETURN(card->ctx, 2, r); + } + + SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2)); +} + +static int ias_select_file(sc_card_t *card, const sc_path_t *in_path, + sc_file_t **file_out) +{ + int r, pathlen, stripped_len, offset; + u8 buf[SC_MAX_APDU_BUFFER_SIZE]; + u8 pathbuf[SC_MAX_PATH_SIZE], *path; + sc_context_t *ctx; + sc_apdu_t apdu, rapdu; + sc_file_t *file; + + r = pathlen = stripped_len = offset = 0; + path = pathbuf; + file = NULL; + + assert(card != NULL && in_path != NULL); + ctx = card->ctx; + + if (in_path->len > SC_MAX_PATH_SIZE) + return SC_ERROR_INVALID_ARGUMENTS; + memcpy(path, in_path->value, in_path->len); + pathlen = in_path->len; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0); + apdu.p2 = 0; /* First record, return FCI */ + + switch (in_path->type) { + case SC_PATH_TYPE_FILE_ID: + apdu.p1 = 2; + if (pathlen != 2) + return SC_ERROR_INVALID_ARGUMENTS; + break; + case SC_PATH_TYPE_DF_NAME: + apdu.p1 = 4; + break; + case SC_PATH_TYPE_PATH: + apdu.p1 = 9; + /* Strip the MF */ + if (pathlen >= 2 && memcmp(path, "\x3f\x00", 2) == 0) { + if (pathlen == 2) { /* Only 3f00 provided */ + apdu.p1 = 0; + break; + } + path += 2; + pathlen -= 2; + } + /* Optimization based on the normal Portuguese eID usage pattern: + * paths with len >= 4 shall be stripped - this avoids unnecessary + * "file not found" errors. Other cards may benefit from this also. + * + * This works perfectly for the Portuguese eID card, but if you + * are adapting this driver to another card, "false positives" may + * occur depending, of course, on the file structure of the card. + * + * Please have this in mind if adapting this driver to another card. + */ + if (pathlen >= 4) { + stripped_len = pathlen - 2; + path += stripped_len; + pathlen = 2; + } else if (pathlen == 2) { + apdu.p1 = 0; + } + break; + case SC_PATH_TYPE_FROM_CURRENT: + apdu.p1 = 9; + break; + case SC_PATH_TYPE_PARENT: + apdu.p1 = 3; + apdu.p2 = 0x0C; + pathlen = 0; + apdu.cse = SC_APDU_CASE_2_SHORT; + break; + default: + SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS); + } + + apdu.lc = pathlen; + apdu.data = path; + apdu.datalen = pathlen; + + if (file_out != NULL) { + apdu.resp = buf; + apdu.resplen = sizeof(buf); + apdu.le = 256; + } else { + apdu.p2 = 0x0C; + apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT; + } + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (file_out == NULL) { + if (apdu.sw1 == 0x61) + SC_FUNC_RETURN(card->ctx, 2, 0); + SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2)); + } + + /* A "file not found" error was received, this can mean two things: + * 1) the file does not exist + * 2) the current DF may be incorrect due to the optimization applied + * earlier. If the path was previously stripped, select the first DF + * and try to re-select the path with the full value. + */ + if (stripped_len > 0 && apdu.sw1 == 0x6A && apdu.sw2 == 0x82) { + sc_file_t *file = NULL; + sc_path_t tpath; + int i; + + /* Restore original path value */ + path -= stripped_len; + pathlen += stripped_len; + + memset(&tpath, 0, sizeof(sc_path_t)); + tpath.type = SC_PATH_TYPE_PATH; + tpath.len = 2; + if(path[0] == 0x3f && path[1] == 0x00) + offset = 2; + else + offset = 0; + tpath.value[0] = path[offset]; + tpath.value[1] = path[offset + 1]; + + /* Go up in the hierarchy to the correct DF */ + r = ias_select_file(card, &tpath, &file); + SC_TEST_RET(card->ctx, r, "Error selecting parent."); + if(file->type != SC_FILE_TYPE_DF) + return SC_ERROR_FILE_NOT_FOUND; + + /* We're now in the right place, reconstruct the APDU and retry */ + path += offset + 2; + pathlen -= offset + 2; + apdu.lc = pathlen; + apdu.data = path; + apdu.datalen = pathlen; + + if (file_out != NULL) + apdu.resplen = sizeof(buf); + + r = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, r, "APDU transmit failed"); + if (file_out == NULL) { + if (apdu.sw1 == 0x61) + SC_FUNC_RETURN(card->ctx, 2, 0); + SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2)); + } + } + + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + SC_FUNC_RETURN(card->ctx, 2, r); + + if (apdu.resplen < 2) + SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED); + switch (apdu.resp[0]) { + case 0x6F: + file = sc_file_new(); + if (file == NULL) + SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_OUT_OF_MEMORY); + file->path = *in_path; + if (card->ops->process_fci == NULL) { + sc_file_free(file); + SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED); + } + if ((size_t)apdu.resp[1] + 2 <= apdu.resplen) + card->ops->process_fci(card, file, apdu.resp+2, apdu.resp[1]); + *file_out = file; + break; + case 0x00: /* proprietary coding */ + SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED); + default: + SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED); + } + + return SC_SUCCESS; +} + +static struct sc_card_driver *sc_get_driver(void) +{ + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); + + if (iso_ops == NULL) + iso_ops = iso_drv->ops; + /* Use the standard iso operations as default */ + ias_ops = *iso_drv->ops; + /* IAS specific functions */ + ias_ops.select_file = ias_select_file; + ias_ops.match_card = ias_match_card; + ias_ops.init = ias_init; + ias_ops.finish = ias_finish; + ias_ops.set_security_env = ias_set_security_env; + ias_ops.compute_signature = ias_compute_signature; + ias_ops.pin_cmd = ias_pin_cmd; + + return &ias_drv; +} + +struct sc_card_driver *sc_get_ias_driver(void) +{ + return sc_get_driver(); +} diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h index 05f32e1e..65c2cc20 100644 --- a/src/libopensc/cards.h +++ b/src/libopensc/cards.h @@ -151,6 +151,15 @@ enum { /* MyEID cards */ SC_CARD_TYPE_MYEID_BASE = 20000, SC_CARD_TYPE_MYEID_GENERIC, + + /* GemsafeV1 cards */ + SC_CARD_TYPE_GEMSAFEV1_BASE = 21000, + SC_CARD_TYPE_GEMSAFEV1_GENERIC, + SC_CARD_TYPE_GEMSAFEV1_PTEID, + + /* IAS cards */ + SC_CARD_TYPE_IAS_BASE = 22000, + SC_CARD_TYPE_IAS_PTEID, }; extern sc_card_driver_t *sc_get_default_driver(void); @@ -181,6 +190,7 @@ extern sc_card_driver_t *sc_get_rutoken_driver(void); extern sc_card_driver_t *sc_get_rtecp_driver(void); extern sc_card_driver_t *sc_get_westcos_driver(void); extern sc_card_driver_t *sc_get_myeid_driver(void); +extern sc_card_driver_t *sc_get_ias_driver(void); #ifdef __cplusplus } diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c index e9832b17..a83c8a83 100644 --- a/src/libopensc/ctx.c +++ b/src/libopensc/ctx.c @@ -71,6 +71,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = { { "oberthur", (void *(*)(void)) sc_get_oberthur_driver }, #endif { "belpic", (void *(*)(void)) sc_get_belpic_driver }, + { "ias", (void *(*)(void)) sc_get_ias_driver }, { "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver }, { "muscle", (void *(*)(void)) sc_get_muscle_driver }, { "incrypto34", (void *(*)(void)) sc_get_incrypto34_driver }, diff --git a/src/libopensc/dir.c b/src/libopensc/dir.c index 634e6e95..b09e6e9c 100644 --- a/src/libopensc/dir.c +++ b/src/libopensc/dir.c @@ -32,7 +32,9 @@ struct app_entry { static const struct app_entry apps[] = { { (const u8 *) "\xA0\x00\x00\x00\x63PKCS-15", 12, "PKCS #15" }, - { (const u8 *) "\xA0\x00\x00\x01\x77PKCS-15", 12, "Belgian eID" }, + { (const u8 *) "\xA0\x00\x00\x01\x77PKCS-15", 12, "Belgian eID" } + /* Needed for the normal PKCS#15 processing of the Portugal eID card */ + /* { (const u8 *) "\x44\x46\x20\x69\x73\x73\x75\x65\x72", 9, "Portugal eID" } */ }; static const struct app_entry * find_app_entry(const u8 * aid, size_t aid_len) diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c new file mode 100644 index 00000000..aefb98ac --- /dev/null +++ b/src/libopensc/pkcs15-pteid.c @@ -0,0 +1,295 @@ +/* + * PKCS15 emulation layer for Portugal eID card. + * + * Copyright (C) 2009, Joao Poupino + * Copyright (C) 2004, Martin Paljak + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Based on the PKCS#15 emulation layer for EstEID card by Martin Paljak + * + */ + +/* + * The card has a valid PKCS#15 file system. However, the private keys + * are missing the SC_PKCS15_CO_FLAG_PRIVATE flag and this causes problems + * with some applications (i.e. they don't work). + * + * The three main objectives of the emulation layer are: + * + * 1. Add the necessary SC_PKCS15_CO_FLAG_PRIVATE flag to private keys. + * 2. Hide "superfluous" PKCS#15 objects, e.g. PUKs (the user can't use them). + * 3. Improve usability by providing more descriptive names for the PINs, Keys, etc. + * + */ + +#include "internal.h" +#include "pkcs15.h" +#include +#include +#include + +#include + +#define IAS_CARD 0 +#define GEMSAFE_CARD 1 + +int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); + +static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card) +{ + int r, i, type; + unsigned char *buf; + size_t len; + sc_pkcs15_tokeninfo_t tokeninfo; + sc_path_t tmppath; + sc_card_t *card = p15card->card; + sc_context_t *ctx = card->ctx; + + /* Parse the TokenInfo EF */ + sc_format_path("3f004f005032", &tmppath); + r = sc_select_file(card, &tmppath, &p15card->file_tokeninfo); + if (r) + goto end; + if ( (len = p15card->file_tokeninfo->size) == 0) { + sc_error(card->ctx, "EF(TokenInfo) is empty\n"); + goto end; + } + buf = malloc(len); + if (buf == NULL) + return SC_ERROR_OUT_OF_MEMORY; + r = sc_read_binary(card, 0, buf, len, 0); + if (r < 0) + goto end; + if (r <= 2) { + r = SC_ERROR_PKCS15_APP_NOT_FOUND; + goto end; + } + memset(&tokeninfo, 0, sizeof(tokeninfo)); + r = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t) r); + if (r != SC_SUCCESS) + goto end; + p15card->version = tokeninfo.version; + p15card->label = tokeninfo.label; + p15card->serial_number = tokeninfo.serial_number; + p15card->manufacturer_id = tokeninfo.manufacturer_id; + p15card->last_update = tokeninfo.last_update; + p15card->flags = tokeninfo.flags; + p15card->preferred_language = tokeninfo.preferred_language; + p15card->seInfo = tokeninfo.seInfo; + p15card->num_seInfo = tokeninfo.num_seInfo; + + /* Card type detection */ + if (card->type == SC_CARD_TYPE_IAS_PTEID) + type = IAS_CARD; + else if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) + type = GEMSAFE_CARD; + else { + r = SC_ERROR_INTERNAL; + goto end; + } + + p15card->flags = SC_PKCS15_CARD_FLAG_PRN_GENERATION + | SC_PKCS15_CARD_FLAG_EID_COMPLIANT + | SC_PKCS15_CARD_FLAG_READONLY; + + /* TODO: Use the cardholder's name? */ + /* TODO: Use Portuguese descriptions? */ + + /* Add X.509 Certificates */ + static const char *pteid_cert_names[4] = { + "AUTHENTICATION CERTIFICATE", + "SIGNATURE CERTIFICATE", + "SIGNATURE SUB CA", + "AUTHENTICATION SUB CA" + }; + /* X.509 Certificate Paths */ + static const char *pteid_cert_paths[4] = { + "3f005f00ef09", /* Authentication Certificate path */ + "3f005f00ef08", /* Digital Signature Certificate path */ + "3f005f00ef0f", /* Signature sub CA path */ + "3f005f00ef10" /* Authentication sub CA path */ + }; + /* X.509 Certificate IDs */ + static const int pteid_cert_ids[4] = {0x45, 0x46, 0x51, 0x52}; + struct sc_pkcs15_cert_info cert_info; + struct sc_pkcs15_object cert_obj; + + for (i = 0; i < 4; i++) { + memset(&cert_info, 0, sizeof(cert_info)); + memset(&cert_obj, 0, sizeof(cert_obj)); + + cert_info.id.value[0] = pteid_cert_ids[i]; + cert_info.id.len = 1; + sc_format_path(pteid_cert_paths[i], &cert_info.path); + strlcpy(cert_obj.label, pteid_cert_names[i], sizeof(cert_obj.label)); + r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info); + if (r < 0) { + r = SC_ERROR_INTERNAL; + goto end; + } + } + + /* Add PINs */ + static const char *pteid_pin_names[3] = { + "Auth PIN", + "Sign PIN", + "Address PIN" + }; + /* PIN References */ + static const int pteid_pin_ref[2][3] = { {1, 130, 131}, {129, 130, 131} }; + /* PIN Authentication IDs */ + static const int pteid_pin_authid[3] = {1, 2, 3}; + /* PIN Paths */ + static const char *pteid_pin_paths[2][3] = { {NULL, "3f005f00", NULL}, + {NULL, NULL, NULL} }; + struct sc_pkcs15_pin_info pin_info; + struct sc_pkcs15_object pin_obj; + + for (i = 0; i < 3; i++) { + memset(&pin_info, 0, sizeof(pin_info)); + memset(&pin_obj, 0, sizeof(pin_obj)); + + pin_info.auth_id.len = 1; + pin_info.auth_id.value[0] = pteid_pin_authid[i]; + pin_info.reference = pteid_pin_ref[type][i]; + pin_info.flags = SC_PKCS15_PIN_FLAG_NEEDS_PADDING + | SC_PKCS15_PIN_FLAG_INITIALIZED + | SC_PKCS15_PIN_FLAG_CASE_SENSITIVE; + pin_info.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; + pin_info.min_length = 4; + pin_info.stored_length = 8; + pin_info.max_length = 8; + pin_info.pad_char = type == IAS_CARD ? 0x2F : 0xFF; + pin_info.tries_left = -1; + if (pteid_pin_paths[type][i] != NULL) + sc_format_path(pteid_pin_paths[type][i], &pin_info.path); + strlcpy(pin_obj.label, pteid_pin_names[i], sizeof(pin_obj.label)); + pin_obj.flags = 0; + r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); + if (r < 0) { + r = SC_ERROR_INTERNAL; + goto end; + } + } + + /* Add Private Keys */ + + /* Key reference */ + static const int pteid_prkey_keyref[2][2] = { {1, 130}, {2, 1} }; + /* RSA Private Key usage */ + static int pteid_prkey_usage[2] = { + SC_PKCS15_PRKEY_USAGE_SIGN, + SC_PKCS15_PRKEY_USAGE_NONREPUDIATION}; + /* RSA Private Key IDs */ + static const int pteid_prkey_ids[2] = {0x45, 0x46}; + static const char *pteid_prkey_names[2] = { + "CITIZEN AUTHENTICATION KEY", + "CITIZEN SIGNATURE KEY"}; + /* RSA Private Key Paths */ + static const char *pteid_prkey_paths[2][2] = { {NULL, "3f005f00"}, {NULL, NULL} }; + struct sc_pkcs15_prkey_info prkey_info; + struct sc_pkcs15_object prkey_obj; + + for (i = 0; i < 2; i++) { + memset(&prkey_info, 0, sizeof(prkey_info)); + memset(&prkey_obj, 0, sizeof(prkey_obj)); + + prkey_info.id.len = 1; + prkey_info.id.value[0] = pteid_prkey_ids[i]; + prkey_info.usage = pteid_prkey_usage[i]; + prkey_info.native = 1; + prkey_info.key_reference = pteid_prkey_keyref[type][i]; + prkey_info.modulus_length = 1024; + if (pteid_prkey_paths[type][i] != NULL) + sc_format_path(pteid_prkey_paths[type][i], &prkey_info.path); + strlcpy(prkey_obj.label, pteid_prkey_names[i], sizeof(prkey_obj.label)); + prkey_obj.auth_id.len = 1; + prkey_obj.auth_id.value[0] = i + 1; + prkey_obj.user_consent = (i == 1) ? 1 : 0; + prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE; + + r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info); + if (r < 0) { + r = SC_ERROR_INTERNAL; + goto end; + } + } + + /* Add objects */ + static const char *object_ids[3] = {"1", "2", "3"}; + static const char *object_oids[3] = {"-1", "-1", "-1"}; + static const char *object_labels[3] = {"Citizen Data", + "Citizen Address Data", + "Citizen Notepad"}; + static const char *object_authids[3] = {"3", "3", "1"}; + static const char *object_paths[3] = {"3f005f00ef02", + "3f005f00ef05", + "3f005f00ef07"}; + static const int object_flags[3] = {0, + SC_PKCS15_CO_FLAG_PRIVATE, + SC_PKCS15_CO_FLAG_MODIFIABLE}; + struct sc_pkcs15_data_info obj_info; + struct sc_pkcs15_object obj_obj; + + for (i = 0; i < 3; i++) { + memset(&obj_info, 0, sizeof(obj_info)); + memset(&obj_obj, 0, sizeof(obj_obj)); + + sc_pkcs15_format_id(object_ids[i], &obj_info.id); + sc_format_path(object_paths[i], &obj_info.path); + r = sc_format_oid(&obj_info.app_oid, object_oids[i]); + if (r != SC_SUCCESS) + goto end; + strlcpy(obj_info.app_label, object_labels[i], SC_PKCS15_MAX_LABEL_SIZE); + if (object_authids[i] != NULL) + sc_pkcs15_format_id(object_authids[i], &obj_obj.auth_id); + strlcpy(obj_obj.label, object_labels[i], SC_PKCS15_MAX_LABEL_SIZE); + obj_obj.flags = object_flags[i]; + + r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info); + if (r < 0) + goto end; + } +end: + if (buf != NULL) { + free(buf); + buf = NULL; + } + if (r) + return r; + + return SC_SUCCESS; +} + +static int pteid_detect_card(sc_pkcs15_card_t *p15card) +{ + if (p15card->card->type == SC_CARD_TYPE_IAS_PTEID || + p15card->card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) + return SC_SUCCESS; + return SC_ERROR_WRONG_CARD; +} + +int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *p15card, sc_pkcs15emu_opt_t *opts) +{ + if (opts != NULL && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK) + return sc_pkcs15emu_pteid_init(p15card); + else { + int r = pteid_detect_card(p15card); + if (r) + return SC_ERROR_WRONG_CARD; + return sc_pkcs15emu_pteid_init(p15card); + } +} diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 58a2e378..7b5deb32 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -56,6 +56,8 @@ extern int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t extern int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); +extern int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); + static struct { const char * name; int (*handler)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); @@ -74,6 +76,7 @@ static struct { { "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex}, { "tccardos", sc_pkcs15emu_tccardos_init_ex }, { "entersafe", sc_pkcs15emu_entersafe_init_ex }, + { "pteid", sc_pkcs15emu_pteid_init_ex }, { NULL, NULL } }; @@ -90,6 +93,8 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card) { switch (card->type) { case SC_CARD_TYPE_MCRD_ESTEID: + case SC_CARD_TYPE_IAS_PTEID: + case SC_CARD_TYPE_GEMSAFEV1_PTEID: return 1; default: return 0; From 64916e01b5b6878a397190a231c2b3c06fb05047 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 3 Oct 2009 17:04:32 +0000 Subject: [PATCH 29/57] Accidental sc_error removed. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3756 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/pkcs15-pteid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libopensc/pkcs15-pteid.c b/src/libopensc/pkcs15-pteid.c index aefb98ac..0fcce9cc 100644 --- a/src/libopensc/pkcs15-pteid.c +++ b/src/libopensc/pkcs15-pteid.c @@ -64,7 +64,7 @@ static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card) if (r) goto end; if ( (len = p15card->file_tokeninfo->size) == 0) { - sc_error(card->ctx, "EF(TokenInfo) is empty\n"); + sc_debug(card->ctx, "EF(TokenInfo) is empty\n"); goto end; } buf = malloc(len); From 91815f380a2620203122bacda1f0662a19220f3f Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 5 Oct 2009 19:59:05 +0000 Subject: [PATCH 30/57] PC/SC: better separation between OpenSC and PC/SC types. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3758 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/reader-pcsc.c | 46 ++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 7d467b31..1f302a65 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -89,9 +89,11 @@ struct pcsc_slot_data { static int pcsc_detect_card_presence(sc_reader_t *reader, sc_slot_info_t *slot); -static int pcsc_ret_to_error(long rv) +static int pcsc_ret_to_error(LONG rv) { switch (rv) { + case SCARD_S_SUCCESS: + return SC_SUCCESS; case SCARD_W_REMOVED_CARD: return SC_ERROR_CARD_REMOVED; case SCARD_E_NOT_TRANSACTED: @@ -113,6 +115,7 @@ static int pcsc_ret_to_error(long rv) return SC_ERROR_CARD_NOT_PRESENT; case SCARD_E_PROTO_MISMATCH: /* Should not happen */ return SC_ERROR_READER; + default: return SC_ERROR_UNKNOWN; } @@ -490,11 +493,11 @@ static int pcsc_reconnect(sc_reader_t * reader, sc_slot_info_t * slot, int reset if (rv != SCARD_S_SUCCESS) { PCSC_ERROR(reader->ctx, "SCardReconnect failed", rv); - return rv; + return pcsc_ret_to_error(rv); } slot->active_protocol = pcsc_proto_to_opensc(active_proto); - return rv; + return pcsc_ret_to_error(rv); } static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot) @@ -533,10 +536,10 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot) if (slot->active_protocol != protocol) { sc_debug(reader->ctx, "Protocol difference, forcing protocol (%d)", protocol); /* Reconnect with a reset. pcsc_reconnect figures out the right forced protocol */ - rv = pcsc_reconnect(reader, slot, 1); - if (rv != SCARD_S_SUCCESS) { - PCSC_ERROR(reader->ctx, "SCardReconnect (to force protocol) failed", rv); - return pcsc_ret_to_error(rv); + r = pcsc_reconnect(reader, slot, 1); + if (r != SC_SUCCESS) { + sc_debug(reader->ctx, "pcsc_reconnect (to force protocol) failed", r); + return r; } sc_debug(reader->ctx, "Proto after reconnect = %d", slot->active_protocol); } @@ -558,7 +561,8 @@ static int pcsc_disconnect(sc_reader_t * reader, sc_slot_info_t * slot) static int pcsc_lock(sc_reader_t *reader, sc_slot_info_t *slot) { - long rv; + LONG rv; + int r; struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot); struct pcsc_private_data *priv = GET_PRIV_DATA(reader); @@ -570,19 +574,19 @@ static int pcsc_lock(sc_reader_t *reader, sc_slot_info_t *slot) switch (rv) { case SCARD_E_INVALID_HANDLE: case SCARD_E_READER_UNAVAILABLE: - rv = pcsc_connect(reader, slot); - if (rv != SCARD_S_SUCCESS) { - PCSC_ERROR(reader->ctx, "SCardConnect failed", rv); - return pcsc_ret_to_error(rv); + r = pcsc_connect(reader, slot); + if (r != SC_SUCCESS) { + sc_debug(reader->ctx, "pcsc_connect failed", r); + return r; } /* return failure so that upper layers will be notified and try to lock again */ return SC_ERROR_READER_REATTACHED; case SCARD_W_RESET_CARD: /* try to reconnect if the card was reset by some other application */ - rv = pcsc_reconnect(reader, slot, 0); - if (rv != SCARD_S_SUCCESS) { - PCSC_ERROR(reader->ctx, "SCardReconnect failed", rv); - return pcsc_ret_to_error(rv); + r = pcsc_reconnect(reader, slot, 0); + if (r != SC_SUCCESS) { + sc_debug(reader->ctx, "pcsc_reconnect failed", r); + return r; } /* return failure so that upper layers will be notified and try to lock again */ return SC_ERROR_CARD_RESET; @@ -597,7 +601,7 @@ static int pcsc_lock(sc_reader_t *reader, sc_slot_info_t *slot) static int pcsc_unlock(sc_reader_t *reader, sc_slot_info_t *slot) { - long rv; + LONG rv; struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot); struct pcsc_private_data *priv = GET_PRIV_DATA(reader); @@ -635,13 +639,13 @@ static int pcsc_reset(sc_reader_t *reader, sc_slot_info_t *slot) int old_locked = pslot->locked; r = pcsc_reconnect(reader, slot, 1); - if(r != SCARD_S_SUCCESS) - return pcsc_ret_to_error(r); + if(r != SC_SUCCESS) + return r; /* pcsc_reconnect unlocks card... try to lock it again if it was locked */ if(old_locked) r = pcsc_lock(reader, slot); - + return r; } @@ -919,7 +923,7 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) rv = gpriv->SCardControl(card_handle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, feature_buf, sizeof(feature_buf), &feature_len); if (rv != SCARD_S_SUCCESS) { sc_debug(ctx, "SCardControl failed %08x", rv); - } + } else { if ((feature_len % sizeof(PCSC_TLV_STRUCTURE)) != 0) { sc_debug(ctx, "Inconsistent TLV from reader!"); From ea370692724dabe3c2b13b35e3623376c12e668c Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 5 Oct 2009 20:10:07 +0000 Subject: [PATCH 31/57] Merged r3749:3758 from trunk git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3759 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-rtecp.c | 57 +++++--- src/libopensc/cardctl.h | 22 ++- src/libopensc/libopensc.exports | 2 + src/libopensc/opensc.h | 11 ++ src/libopensc/pkcs15-algo.c | 3 + src/libopensc/pkcs15-prkey.c | 121 ++++++++++++---- src/libopensc/pkcs15-pubkey.c | 192 ++++++++++++++++++++++---- src/libopensc/pkcs15.c | 7 + src/libopensc/pkcs15.h | 29 ++++ src/pkcs11/framework-pkcs15.c | 208 +++++++++++++++++++++++++--- src/pkcs11/mechanism.c | 20 +++ src/pkcs11/openssl.c | 119 +++++++++++++++- src/pkcs11/pkcs11.h | 8 ++ src/pkcs11/sc-pkcs11.h | 1 + src/pkcs15init/pkcs15-init.h | 6 + src/pkcs15init/pkcs15-lib.c | 45 +++++- src/pkcs15init/pkcs15-rtecp.c | 236 +++++++++++++++++++++++--------- 17 files changed, 930 insertions(+), 157 deletions(-) diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 550e8da3..402c7a82 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -53,6 +53,7 @@ static int rtecp_match_card(sc_card_t *card) static int rtecp_init(sc_card_t *card) { + sc_algorithm_info_t info; unsigned long flags; assert(card && card->ctx); @@ -72,6 +73,13 @@ static int rtecp_init(sc_card_t *card) _sc_card_add_rsa_alg(card, 1792, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); + memset(&info, 0, sizeof(info)); + info.algorithm = SC_ALGORITHM_GOSTR3410; + info.key_length = 256; + info.flags = SC_ALGORITHM_GOSTR3410_RAW | SC_ALGORITHM_ONBOARD_KEY_GEN + | SC_ALGORITHM_GOSTR3410_HASH_NONE; + _sc_card_add_algorithm(card, &info); + SC_FUNC_RETURN(card->ctx, 2, 0); } @@ -374,7 +382,7 @@ static int rtecp_logout(sc_card_t *card) SC_FUNC_RETURN(card->ctx, 2, r); } -static int rtecp_rsa_cipher(sc_card_t *card, const u8 *data, size_t data_len, +static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len, u8 *out, size_t out_len, int sign) { sc_apdu_t apdu; @@ -383,7 +391,7 @@ static int rtecp_rsa_cipher(sc_card_t *card, const u8 *data, size_t data_len, int r; assert(card && card->ctx && data && out); - buf_out = malloc(data_len + 2); + buf_out = malloc(out_len + 2); buf = malloc(data_len); if (!buf || !buf_out) { @@ -403,8 +411,8 @@ static int rtecp_rsa_cipher(sc_card_t *card, const u8 *data, size_t data_len, apdu.data = buf; apdu.datalen = data_len; apdu.resp = buf_out; - apdu.resplen = data_len + 2; - apdu.le = data_len; + apdu.resplen = out_len + 2; + apdu.le = out_len; if (apdu.lc > 255) apdu.flags |= SC_APDU_FLAGS_CHAINING; r = sc_transmit_apdu(card, &apdu); @@ -422,8 +430,8 @@ static int rtecp_rsa_cipher(sc_card_t *card, const u8 *data, size_t data_len, if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { assert(buf_out); - for (i = 0; i < out_len && i < data_len && i < apdu.resplen; ++i) - out[i] = buf_out[data_len - 1 - i]; + for (i = 0; i < out_len && i < apdu.resplen; ++i) + out[i] = buf_out[out_len - 1 - i]; r = (i > 0) ? (int)i : SC_ERROR_INTERNAL; } else @@ -432,7 +440,7 @@ static int rtecp_rsa_cipher(sc_card_t *card, const u8 *data, size_t data_len, if (!sign) { assert(buf_out); - sc_mem_clear(buf_out, data_len + 2); + sc_mem_clear(buf_out, out_len + 2); } assert(buf_out); free(buf_out); @@ -447,7 +455,7 @@ static int rtecp_decipher(sc_card_t *card, assert(card && card->ctx && data && out); /* decipher */ - r = rtecp_rsa_cipher(card, data, data_len, out, out_len, 0); + r = rtecp_cipher(card, data, data_len, out, out_len, 0); SC_FUNC_RETURN(card->ctx, 3, r); } @@ -458,7 +466,7 @@ static int rtecp_compute_signature(sc_card_t *card, assert(card && card->ctx && data && out); /* compute digital signature */ - r = rtecp_rsa_cipher(card, data, data_len, out, out_len, 1); + r = rtecp_cipher(card, data, data_len, out, out_len, 1); SC_FUNC_RETURN(card->ctx, 2, r); } @@ -663,14 +671,31 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data) r = sc_check_sw(card, apdu.sw1, apdu.sw2); if (!r && request == SC_CARDCTL_RTECP_GENERATE_KEY) { - if (genkey_data->modulus_len >= apdu.resplen && - genkey_data->exponent_len >= 3) + if (genkey_data->type == SC_ALGORITHM_RSA && + genkey_data->u.rsa.modulus_len >= apdu.resplen && + genkey_data->u.rsa.exponent_len >= 3) { - memcpy(genkey_data->modulus, apdu.resp, apdu.resplen); - genkey_data->modulus_len = apdu.resplen; - reverse(genkey_data->modulus, genkey_data->modulus_len); - memcpy(genkey_data->exponent, "\x01\x00\x01", 3); - genkey_data->exponent_len = 3; + memcpy(genkey_data->u.rsa.modulus, apdu.resp, apdu.resplen); + genkey_data->u.rsa.modulus_len = apdu.resplen; + reverse(genkey_data->u.rsa.modulus, + genkey_data->u.rsa.modulus_len); + memcpy(genkey_data->u.rsa.exponent, "\x01\x00\x01", 3); + genkey_data->u.rsa.exponent_len = 3; + } + else if (genkey_data->type == SC_ALGORITHM_GOSTR3410 && + genkey_data->u.gostr3410.x_len <= apdu.resplen && + genkey_data->u.gostr3410.x_len + + genkey_data->u.gostr3410.y_len >= apdu.resplen) + { + memcpy(genkey_data->u.gostr3410.x, apdu.resp, + genkey_data->u.gostr3410.x_len); + memcpy(genkey_data->u.gostr3410.y, apdu.resp + + genkey_data->u.gostr3410.x_len, + genkey_data->u.gostr3410.y_len); + reverse(genkey_data->u.gostr3410.x, + genkey_data->u.gostr3410.x_len); + reverse(genkey_data->u.gostr3410.y, + genkey_data->u.gostr3410.y_len); } else r = SC_ERROR_BUFFER_TOO_SMALL; diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 409c89b9..916728e8 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -691,11 +691,25 @@ typedef struct sc_entersafe_gen_key_data_st { * Rutoken ECP stuff */ typedef struct sc_rtecp_genkey_data { + unsigned int type; unsigned int key_id; - unsigned char *exponent; - size_t exponent_len; - unsigned char *modulus; - size_t modulus_len; + union + { + struct + { + unsigned char *exponent; + size_t exponent_len; + unsigned char *modulus; + size_t modulus_len; + } rsa; + struct + { + unsigned char *x; + size_t x_len; + unsigned char *y; + size_t y_len; + } gostr3410; + } u; } sc_rtecp_genkey_data_t; /* diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index f3d0e76e..7276210b 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -106,6 +106,7 @@ sc_pkcs15_decode_prkey sc_pkcs15_decode_pubkey sc_pkcs15_decode_pubkey_dsa sc_pkcs15_decode_pubkey_rsa +sc_pkcs15_decode_pubkey_gostr3410 sc_pkcs15_decode_pukdf_entry sc_pkcs15_encode_aodf_entry sc_pkcs15_encode_cdf_entry @@ -118,6 +119,7 @@ sc_pkcs15_encode_prkey sc_pkcs15_encode_pubkey sc_pkcs15_encode_pubkey_dsa sc_pkcs15_encode_pubkey_rsa +sc_pkcs15_encode_pubkey_gostr3410 sc_pkcs15_encode_pukdf_entry sc_pkcs15_encode_tokeninfo sc_pkcs15_encode_unusedspace diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 111fa73b..0b91564b 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -147,6 +147,7 @@ extern "C" { #define SC_ALGORITHM_RSA 0 #define SC_ALGORITHM_DSA 1 #define SC_ALGORITHM_EC 2 +#define SC_ALGORITHM_GOSTR3410 3 /* Symmetric algorithms */ #define SC_ALGORITHM_DES 64 @@ -156,7 +157,11 @@ extern "C" { /* Hash algorithms */ #define SC_ALGORITHM_MD5 128 #define SC_ALGORITHM_SHA1 129 +#define SC_ALGORITHM_GOSTR3411 130 +/* FIXME: */ +/* #define SC_ALGORITHM_GOSTHASH 130 +*/ /* Key derivation algorithms */ #define SC_ALGORITHM_PBKDF2 192 @@ -190,6 +195,12 @@ extern "C" { #define SC_ALGORITHM_RSA_HASH_SHA224 0x00001000 #define SC_ALGORITHM_RSA_HASHES 0x00001FE0 +#define SC_ALGORITHM_GOSTR3410_RAW 0x00002000 +#define SC_ALGORITHM_GOSTR3410_HASH_NONE 0x00004000 +#define SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411 0x00008000 +#define SC_ALGORITHM_GOSTR3410_HASHES 0x00008000 + +/* FIXME: */ #define SC_ALGORITHM_GOST_CRYPT_PZ 0x0 #define SC_ALGORITHM_GOST_CRYPT_GAMM 0x1 #define SC_ALGORITHM_GOST_CRYPT_GAMMOS 0x2 diff --git a/src/libopensc/pkcs15-algo.c b/src/libopensc/pkcs15-algo.c index 9bc24a56..af3c22dc 100644 --- a/src/libopensc/pkcs15-algo.c +++ b/src/libopensc/pkcs15-algo.c @@ -239,6 +239,9 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = { NULL, NULL }, #endif +#ifdef SC_ALGORITHM_GOSTR3410 + { SC_ALGORITHM_GOSTR3410, {{ 1, 2, 643, 2, 2, 19 }}, NULL, NULL, NULL }, +#endif /* We do not support PBES1 because the encryption is weak */ #ifdef SC_ALGORITHM_PBKDF2 { SC_ALGORITHM_PBKDF2, {{ 1, 2, 840, 113549, 1, 5, 12 }}, diff --git a/src/libopensc/pkcs15-prkey.c b/src/libopensc/pkcs15-prkey.c index e3431af1..aaecba3f 100644 --- a/src/libopensc/pkcs15-prkey.c +++ b/src/libopensc/pkcs15-prkey.c @@ -52,6 +52,19 @@ static const struct sc_asn1_entry c_asn1_prk_rsa_attr[] = { { NULL, 0, 0, 0, NULL, NULL } }; +static const struct sc_asn1_entry c_asn1_gostr3410key_attr[] = { + { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, + { "params_r3410", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "params_r3411", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { "params_28147", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +static const struct sc_asn1_entry c_asn1_prk_gostr3410_attr[] = { + { "privateGOSTR3410KeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + static const struct sc_asn1_entry c_asn1_dsakey_i_p_attr[] = { { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } @@ -76,8 +89,9 @@ static const struct sc_asn1_entry c_asn1_prk_dsa_attr[] = { static const struct sc_asn1_entry c_asn1_prkey[] = { { "privateRSAKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, { "privateDSAKey", SC_ASN1_PKCS15_OBJECT, 2 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, + { "privateGOSTR3410Key", SC_ASN1_PKCS15_OBJECT, 3 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } -}; +}; int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, @@ -85,7 +99,8 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, { sc_context_t *ctx = p15card->card->ctx; struct sc_pkcs15_prkey_info info; - int r; + int r, gostr3410_params[3]; + struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; size_t usage_len = sizeof(info.usage); size_t af_len = sizeof(info.access_flags); struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_prkey_attr[1]; @@ -93,30 +108,37 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, struct sc_asn1_entry asn1_dsakey_attr[2], asn1_prk_dsa_attr[2], asn1_dsakey_i_p_attr[2], asn1_dsakey_value_attr[3]; - struct sc_asn1_entry asn1_prkey[3]; + struct sc_asn1_entry asn1_gostr3410key_attr[5], asn1_prk_gostr3410_attr[2]; + struct sc_asn1_entry asn1_prkey[4]; struct sc_asn1_pkcs15_object rsa_prkey_obj = { obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_rsa_attr }; struct sc_asn1_pkcs15_object dsa_prkey_obj = { obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_dsa_attr }; + struct sc_asn1_pkcs15_object gostr3410_prkey_obj = { obj, asn1_com_key_attr, + asn1_com_prkey_attr, + asn1_prk_gostr3410_attr }; - sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey); + sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey); - sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr); - sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); - sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr); - sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); + sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr); + sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); + sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr); + sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); sc_copy_asn1_entry(c_asn1_dsakey_value_attr, asn1_dsakey_value_attr); - sc_copy_asn1_entry(c_asn1_dsakey_i_p_attr, - asn1_dsakey_i_p_attr); + sc_copy_asn1_entry(c_asn1_dsakey_i_p_attr, asn1_dsakey_i_p_attr); + sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr); + sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); - sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr); - sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); + sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr); + sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); sc_format_asn1_entry(asn1_prkey + 0, &rsa_prkey_obj, NULL, 0); sc_format_asn1_entry(asn1_prkey + 1, &dsa_prkey_obj, NULL, 0); + sc_format_asn1_entry(asn1_prkey + 2, &gostr3410_prkey_obj, NULL, 0); sc_format_asn1_entry(asn1_prk_rsa_attr + 0, asn1_rsakey_attr, NULL, 0); sc_format_asn1_entry(asn1_prk_dsa_attr + 0, asn1_dsakey_attr, NULL, 0); + sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 0); sc_format_asn1_entry(asn1_rsakey_attr + 0, &info.path, NULL, 0); sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0); @@ -126,6 +148,10 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_dsakey_value_attr + 1, asn1_dsakey_i_p_attr, NULL, 0); sc_format_asn1_entry(asn1_dsakey_i_p_attr + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0); sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0); sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0); @@ -137,6 +163,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, memset(&info, 0, sizeof(info)); info.key_reference = -1; info.native = 1; + memset(gostr3410_params, 0, sizeof(gostr3410_params)); r = sc_asn1_decode_choice(ctx, asn1_prkey, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) @@ -149,16 +176,36 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card, /* If the value was indirect-protected, mark the path */ if (asn1_dsakey_i_p_attr[0].flags & SC_ASN1_PRESENT) info.path.type = SC_PATH_TYPE_PATH_PROT; + } else if (asn1_prkey[2].flags & SC_ASN1_PRESENT) { + obj->type = SC_PKCS15_TYPE_PRKEY_GOSTR3410; + assert(info.modulus_length == 0); + info.modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; + assert(info.params_len == 0); + info.params_len = sizeof(struct sc_pkcs15_keyinfo_gostparams); + info.params = malloc(info.params_len); + if (info.params == NULL) + SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY); + assert(sizeof(*keyinfo_gostparams) == info.params_len); + keyinfo_gostparams = info.params; + keyinfo_gostparams->gostr3410 = gostr3410_params[0]; + keyinfo_gostparams->gostr3411 = gostr3410_params[1]; + keyinfo_gostparams->gost28147 = gostr3410_params[2]; } else { - sc_debug(ctx, "Neither RSA or DSA key in PrKDF entry.\n"); + sc_debug(ctx, "Neither RSA or DSA or GOSTR3410 key in PrKDF entry.\n"); SC_FUNC_RETURN(ctx, 0, SC_ERROR_INVALID_ASN1_OBJECT); } r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); - if (r < 0) + if (r < 0) { + if (info.params) + free(info.params); return r; + } obj->data = malloc(sizeof(info)); - if (obj->data == NULL) + if (obj->data == NULL) { + if (info.params) + free(info.params); SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY); + } memcpy(obj->data, &info, sizeof(info)); return 0; @@ -173,27 +220,34 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx, struct sc_asn1_entry asn1_dsakey_attr[2], asn1_prk_dsa_attr[2], asn1_dsakey_value_attr[3], asn1_dsakey_i_p_attr[2]; - struct sc_asn1_entry asn1_prkey[3]; + struct sc_asn1_entry asn1_gostr3410key_attr[5], asn1_prk_gostr3410_attr[2]; + struct sc_asn1_entry asn1_prkey[4]; struct sc_asn1_pkcs15_object rsa_prkey_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_rsa_attr }; struct sc_asn1_pkcs15_object dsa_prkey_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_prkey_attr, asn1_prk_dsa_attr }; + struct sc_asn1_pkcs15_object gostr3410_prkey_obj = { (struct sc_pkcs15_object *) obj, + asn1_com_key_attr, asn1_com_prkey_attr, + asn1_prk_gostr3410_attr }; struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data; + struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; int r; size_t af_len, usage_len; - sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey); + sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey); - sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr); - sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); - sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr); - sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); + sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr); + sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); + sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr); + sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); sc_copy_asn1_entry(c_asn1_dsakey_value_attr, asn1_dsakey_value_attr); sc_copy_asn1_entry(c_asn1_dsakey_i_p_attr, asn1_dsakey_i_p_attr); + sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr); + sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); - sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr); - sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); + sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr); + sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); switch (obj->type) { case SC_PKCS15_TYPE_PRKEY_RSA: @@ -217,6 +271,21 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx, &prkey->path, NULL, 1); } break; + case SC_PKCS15_TYPE_PRKEY_GOSTR3410: + sc_format_asn1_entry(asn1_prkey + 2, &gostr3410_prkey_obj, NULL, 1); + sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 1); + sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &prkey->path, NULL, 1); + if (prkey->params_len == sizeof(*keyinfo_gostparams)) + { + keyinfo_gostparams = prkey->params; + sc_format_asn1_entry(asn1_gostr3410key_attr + 1, + &keyinfo_gostparams->gostr3410, NULL, 1); + sc_format_asn1_entry(asn1_gostr3410key_attr + 2, + &keyinfo_gostparams->gostr3411, NULL, 1); + sc_format_asn1_entry(asn1_gostr3410key_attr + 3, + &keyinfo_gostparams->gost28147, NULL, 1); + } + break; default: sc_debug(ctx, "Invalid private key type: %X\n", obj->type); SC_FUNC_RETURN(ctx, 0, SC_ERROR_INTERNAL); @@ -404,6 +473,10 @@ sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key) free(key->u.dsa.g.data); free(key->u.dsa.priv.data); break; + case SC_ALGORITHM_GOSTR3410: + assert(key->u.gostr3410.d.data); + free(key->u.gostr3410.d.data); + break; } sc_mem_clear(key, sizeof(key)); } @@ -419,5 +492,7 @@ void sc_pkcs15_free_prkey_info(sc_pkcs15_prkey_info_t *key) { if (key->subject) free(key->subject); + if (key->params) + free(key->params); free(key); } diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index ab619f91..507fa546 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -62,9 +62,23 @@ static const struct sc_asn1_entry c_asn1_dsa_type_attr[] = { { NULL, 0, 0, 0, NULL, NULL } }; +static const struct sc_asn1_entry c_asn1_gostr3410key_attr[] = { + { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, + { "params_r3410", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, + { "params_r3411", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { "params_28147", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + +static const struct sc_asn1_entry c_asn1_gostr3410_type_attr[] = { + { "publicGOSTR3410KeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + static const struct sc_asn1_entry c_asn1_pubkey_choice[] = { { "publicRSAKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, { "publicDSAKey", SC_ASN1_PKCS15_OBJECT, 2 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL }, + { "publicGOSTR3410Key", SC_ASN1_PKCS15_OBJECT, 3 | SC_ASN1_CTX | SC_ASN1_CONS, 0, NULL, NULL }, { NULL, 0, 0, 0, NULL, NULL } }; @@ -77,32 +91,39 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, const u8 ** buf, size_t *buflen) { - sc_context_t *ctx = p15card->card->ctx; - struct sc_pkcs15_pubkey_info info; - int r; + sc_context_t *ctx = p15card->card->ctx; + struct sc_pkcs15_pubkey_info info; + int r, gostr3410_params[3]; + struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; size_t usage_len = sizeof(info.usage); size_t af_len = sizeof(info.access_flags); struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_pubkey_attr[1]; struct sc_asn1_entry asn1_rsakey_attr[4], asn1_rsa_type_attr[2]; struct sc_asn1_entry asn1_dsakey_attr[2], asn1_dsa_type_attr[2]; - struct sc_asn1_entry asn1_pubkey_choice[3]; + struct sc_asn1_entry asn1_gostr3410key_attr[5], asn1_gostr3410_type_attr[2]; + struct sc_asn1_entry asn1_pubkey_choice[4]; struct sc_asn1_entry asn1_pubkey[2]; struct sc_asn1_pkcs15_object rsakey_obj = { obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_rsa_type_attr }; struct sc_asn1_pkcs15_object dsakey_obj = { obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_dsa_type_attr }; + struct sc_asn1_pkcs15_object gostr3410key_obj = { obj, asn1_com_key_attr, + asn1_com_pubkey_attr, asn1_gostr3410_type_attr }; - sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey); - sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice); - sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr); - sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); - sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr); - sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); - sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr); - sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); + sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey); + sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice); + sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr); + sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); + sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr); + sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); + sc_copy_asn1_entry(c_asn1_gostr3410_type_attr, asn1_gostr3410_type_attr); + sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); + sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr); + sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); sc_format_asn1_entry(asn1_pubkey_choice + 0, &rsakey_obj, NULL, 0); sc_format_asn1_entry(asn1_pubkey_choice + 1, &dsakey_obj, NULL, 0); + sc_format_asn1_entry(asn1_pubkey_choice + 2, &gostr3410key_obj, NULL, 0); sc_format_asn1_entry(asn1_rsa_type_attr + 0, asn1_rsakey_attr, NULL, 0); @@ -113,6 +134,13 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_dsakey_attr + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 0); + + sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0); + sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0); + sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0); sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0); sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0); @@ -121,10 +149,11 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, sc_format_asn1_entry(asn1_pubkey + 0, asn1_pubkey_choice, NULL, 0); - /* Fill in defaults */ - memset(&info, 0, sizeof(info)); + /* Fill in defaults */ + memset(&info, 0, sizeof(info)); info.key_reference = -1; info.native = 1; + memset(gostr3410_params, 0, sizeof(gostr3410_params)); r = sc_asn1_decode(ctx, asn1_pubkey, *buf, *buflen, buf, buflen); if (r == SC_ERROR_ASN1_END_OF_CONTENTS) @@ -132,19 +161,40 @@ int sc_pkcs15_decode_pukdf_entry(struct sc_pkcs15_card *p15card, SC_TEST_RET(ctx, r, "ASN.1 decoding failed"); if (asn1_pubkey_choice[0].flags & SC_ASN1_PRESENT) { obj->type = SC_PKCS15_TYPE_PUBKEY_RSA; + } else if (asn1_pubkey_choice[2].flags & SC_ASN1_PRESENT) { + obj->type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; + assert(info.modulus_length == 0); + info.modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE; + assert(info.params_len == 0); + info.params_len = sizeof(struct sc_pkcs15_keyinfo_gostparams); + info.params = malloc(info.params_len); + if (info.params == NULL) + SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY); + assert(sizeof(*keyinfo_gostparams) == info.params_len); + keyinfo_gostparams = info.params; + keyinfo_gostparams->gostr3410 = (unsigned int)gostr3410_params[0]; + keyinfo_gostparams->gostr3411 = (unsigned int)gostr3410_params[1]; + keyinfo_gostparams->gost28147 = (unsigned int)gostr3410_params[2]; } else { obj->type = SC_PKCS15_TYPE_PUBKEY_DSA; } r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path); - if (r < 0) + if (r < 0) { + if (info.params) + free(info.params); return r; + } obj->data = malloc(sizeof(info)); - if (obj->data == NULL) + if (obj->data == NULL) { + if (info.params) + free(info.params); SC_FUNC_RETURN(ctx, 0, SC_ERROR_OUT_OF_MEMORY); + } memcpy(obj->data, &info, sizeof(info)); return 0; } + int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx, const struct sc_pkcs15_object *obj, u8 **buf, size_t *buflen) @@ -152,27 +202,34 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx, struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_pubkey_attr[1]; struct sc_asn1_entry asn1_rsakey_attr[4], asn1_rsa_type_attr[2]; struct sc_asn1_entry asn1_dsakey_attr[2], asn1_dsa_type_attr[2]; - struct sc_asn1_entry asn1_pubkey_choice[3]; + struct sc_asn1_entry asn1_gostr3410key_attr[5], asn1_gostr3410_type_attr[2]; + struct sc_asn1_entry asn1_pubkey_choice[4]; struct sc_asn1_entry asn1_pubkey[2]; struct sc_pkcs15_pubkey_info *pubkey = - (struct sc_pkcs15_pubkey_info *) obj->data; + (struct sc_pkcs15_pubkey_info *) obj->data; struct sc_asn1_pkcs15_object rsakey_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_rsa_type_attr }; struct sc_asn1_pkcs15_object dsakey_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr, asn1_com_pubkey_attr, asn1_dsa_type_attr }; + struct sc_asn1_pkcs15_object gostr3410key_obj = { (struct sc_pkcs15_object *) obj, + asn1_com_key_attr, + asn1_com_pubkey_attr, asn1_gostr3410_type_attr }; + struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; int r; size_t af_len, usage_len; - sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey); - sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice); - sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr); - sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); - sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr); - sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); - sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr); - sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); + sc_copy_asn1_entry(c_asn1_pubkey, asn1_pubkey); + sc_copy_asn1_entry(c_asn1_pubkey_choice, asn1_pubkey_choice); + sc_copy_asn1_entry(c_asn1_rsa_type_attr, asn1_rsa_type_attr); + sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr); + sc_copy_asn1_entry(c_asn1_dsa_type_attr, asn1_dsa_type_attr); + sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr); + sc_copy_asn1_entry(c_asn1_gostr3410_type_attr, asn1_gostr3410_type_attr); + sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr); + sc_copy_asn1_entry(c_asn1_com_pubkey_attr, asn1_com_pubkey_attr); + sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr); switch (obj->type) { case SC_PKCS15_TYPE_PUBKEY_RSA: @@ -191,6 +248,24 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx, sc_format_asn1_entry(asn1_dsakey_attr + 0, &pubkey->path, NULL, 1); break; + + case SC_PKCS15_TYPE_PUBKEY_GOSTR3410: + sc_format_asn1_entry(asn1_pubkey_choice + 2, &gostr3410key_obj, NULL, 1); + + sc_format_asn1_entry(asn1_gostr3410_type_attr + 0, asn1_gostr3410key_attr, NULL, 1); + + sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &pubkey->path, NULL, 1); + if (pubkey->params_len == sizeof(*keyinfo_gostparams)) + { + keyinfo_gostparams = pubkey->params; + sc_format_asn1_entry(asn1_gostr3410key_attr + 1, + &keyinfo_gostparams->gostr3410, NULL, 1); + sc_format_asn1_entry(asn1_gostr3410key_attr + 2, + &keyinfo_gostparams->gostr3411, NULL, 1); + sc_format_asn1_entry(asn1_gostr3410key_attr + 3, + &keyinfo_gostparams->gost28147, NULL, 1); + } + break; default: sc_debug(ctx, "Unsupported public key type: %X\n", obj->type); SC_FUNC_RETURN(ctx, 0, SC_ERROR_INTERNAL); @@ -236,6 +311,12 @@ static struct sc_asn1_entry c_asn1_dsa_pub_coefficients[5] = { { NULL, 0, 0, 0, NULL, NULL }, }; +static struct sc_asn1_entry c_asn1_gostr3410_pub_coefficients[3] = { + { "x", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC/*|SC_ASN1_UNSIGNED*/, NULL, NULL }, + { "y", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC/*|SC_ASN1_UNSIGNED*/, NULL, NULL }, + { NULL, 0, 0, 0, NULL, NULL } +}; + int sc_pkcs15_decode_pubkey_rsa(sc_context_t *ctx, struct sc_pkcs15_pubkey_rsa *key, @@ -341,6 +422,50 @@ sc_pkcs15_encode_pubkey_dsa(sc_context_t *ctx, return 0; } +int +sc_pkcs15_decode_pubkey_gostr3410(sc_context_t *ctx, + struct sc_pkcs15_pubkey_gostr3410 *key, + const u8 *buf, size_t buflen) +{ + struct sc_asn1_entry asn1_public_key[2]; + struct sc_asn1_entry asn1_gostr3410_coeff[3]; + int r; + + sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); + sc_format_asn1_entry(asn1_public_key + 0, asn1_gostr3410_coeff, NULL, 0); + + sc_copy_asn1_entry(c_asn1_gostr3410_pub_coefficients, asn1_gostr3410_coeff); + sc_format_asn1_entry(asn1_gostr3410_coeff + 0, &key->x.data, &key->x.len, 0); + sc_format_asn1_entry(asn1_gostr3410_coeff + 1, &key->y.data, &key->y.len, 0); + + r = sc_asn1_decode(ctx, asn1_public_key, buf, buflen, NULL, NULL); + SC_TEST_RET(ctx, r, "ASN.1 parsing of public key failed"); + + return 0; +} + +int +sc_pkcs15_encode_pubkey_gostr3410(sc_context_t *ctx, + struct sc_pkcs15_pubkey_gostr3410 *key, + u8 **buf, size_t *buflen) +{ + struct sc_asn1_entry asn1_public_key[2]; + struct sc_asn1_entry asn1_gostr3410_pub_coeff[3]; + int r; + + sc_copy_asn1_entry(c_asn1_public_key, asn1_public_key); + sc_format_asn1_entry(asn1_public_key + 0, asn1_gostr3410_pub_coeff, NULL, 1); + + sc_copy_asn1_entry(c_asn1_gostr3410_pub_coefficients, asn1_gostr3410_pub_coeff); + sc_format_asn1_entry(asn1_gostr3410_pub_coeff + 0, key->x.data, &key->x.len, 1); + sc_format_asn1_entry(asn1_gostr3410_pub_coeff + 1, key->y.data, &key->y.len, 1); + + r = sc_asn1_encode(ctx, asn1_public_key, buf, buflen); + SC_TEST_RET(ctx, r, "ASN.1 encoding failed"); + + return 0; +} + int sc_pkcs15_encode_pubkey(sc_context_t *ctx, struct sc_pkcs15_pubkey *key, @@ -350,6 +475,9 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx, return sc_pkcs15_encode_pubkey_rsa(ctx, &key->u.rsa, buf, len); if (key->algorithm == SC_ALGORITHM_DSA) return sc_pkcs15_encode_pubkey_dsa(ctx, &key->u.dsa, buf, len); + if (key->algorithm == SC_ALGORITHM_GOSTR3410) + return sc_pkcs15_encode_pubkey_gostr3410(ctx, + &key->u.gostr3410, buf, len); sc_debug(ctx, "Encoding of public key type %u not supported\n", key->algorithm); return SC_ERROR_NOT_SUPPORTED; @@ -364,6 +492,9 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx, return sc_pkcs15_decode_pubkey_rsa(ctx, &key->u.rsa, buf, len); if (key->algorithm == SC_ALGORITHM_DSA) return sc_pkcs15_decode_pubkey_dsa(ctx, &key->u.dsa, buf, len); + if (key->algorithm == SC_ALGORITHM_GOSTR3410) + return sc_pkcs15_decode_pubkey_gostr3410(ctx, + &key->u.gostr3410, buf, len); sc_debug(ctx, "Decoding of public key type %u not supported\n", key->algorithm); return SC_ERROR_NOT_SUPPORTED; @@ -393,6 +524,9 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, case SC_PKCS15_TYPE_PUBKEY_DSA: algorithm = SC_ALGORITHM_DSA; break; + case SC_PKCS15_TYPE_PUBKEY_GOSTR3410: + algorithm = SC_ALGORITHM_GOSTR3410; + break; default: sc_debug(p15card->card->ctx, "Unsupported public key type."); return SC_ERROR_NOT_SUPPORTED; @@ -436,6 +570,10 @@ void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key) free(key->u.dsa.p.data); free(key->u.dsa.q.data); break; + case SC_ALGORITHM_GOSTR3410: + free(key->u.gostr3410.x.data); + free(key->u.gostr3410.y.data); + break; } free(key->data.value); sc_mem_clear(key, sizeof(*key)); @@ -451,5 +589,7 @@ void sc_pkcs15_free_pubkey_info(sc_pkcs15_pubkey_info_t *key) { if (key->subject) free(key->subject); + if (key->params) + free(key->params); free(key); } diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index ad70a491..7292893e 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -907,9 +907,11 @@ static int compare_obj_id(struct sc_pkcs15_object *obj, const sc_pkcs15_id_t *id return sc_pkcs15_compare_id(&((struct sc_pkcs15_cert_info *) data)->id, id); case SC_PKCS15_TYPE_PRKEY_RSA: case SC_PKCS15_TYPE_PRKEY_DSA: + case SC_PKCS15_TYPE_PRKEY_GOSTR3410: return sc_pkcs15_compare_id(&((struct sc_pkcs15_prkey_info *) data)->id, id); case SC_PKCS15_TYPE_PUBKEY_RSA: case SC_PKCS15_TYPE_PUBKEY_DSA: + case SC_PKCS15_TYPE_PUBKEY_GOSTR3410: return sc_pkcs15_compare_id(&((struct sc_pkcs15_pubkey_info *) data)->id, id); case SC_PKCS15_TYPE_AUTH_PIN: return sc_pkcs15_compare_id(&((struct sc_pkcs15_pin_info *) data)->auth_id, id); @@ -934,10 +936,12 @@ static int compare_obj_usage(sc_pkcs15_object_t *obj, unsigned int mask, unsigne switch (obj->type) { case SC_PKCS15_TYPE_PRKEY_RSA: case SC_PKCS15_TYPE_PRKEY_DSA: + case SC_PKCS15_TYPE_PRKEY_GOSTR3410: usage = ((struct sc_pkcs15_prkey_info *) data)->usage; break; case SC_PKCS15_TYPE_PUBKEY_RSA: case SC_PKCS15_TYPE_PUBKEY_DSA: + case SC_PKCS15_TYPE_PUBKEY_GOSTR3410: usage = ((struct sc_pkcs15_pubkey_info *) data)->usage; break; default: @@ -972,6 +976,7 @@ static int compare_obj_reference(sc_pkcs15_object_t *obj, int value) break; case SC_PKCS15_TYPE_PRKEY_RSA: case SC_PKCS15_TYPE_PRKEY_DSA: + case SC_PKCS15_TYPE_PRKEY_GOSTR3410: reference = ((struct sc_pkcs15_prkey_info *) data)->key_reference; break; default: @@ -989,9 +994,11 @@ static int compare_obj_path(sc_pkcs15_object_t *obj, const sc_path_t *path) return sc_compare_path(&((struct sc_pkcs15_cert_info *) data)->path, path); case SC_PKCS15_TYPE_PRKEY_RSA: case SC_PKCS15_TYPE_PRKEY_DSA: + case SC_PKCS15_TYPE_PRKEY_GOSTR3410: return sc_compare_path(&((struct sc_pkcs15_prkey_info *) data)->path, path); case SC_PKCS15_TYPE_PUBKEY_RSA: case SC_PKCS15_TYPE_PUBKEY_DSA: + case SC_PKCS15_TYPE_PUBKEY_GOSTR3410: return sc_compare_path(&((struct sc_pkcs15_pubkey_info *) data)->path, path); case SC_PKCS15_TYPE_AUTH_PIN: return sc_compare_path(&((struct sc_pkcs15_pin_info *) data)->path, path); diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 64a237f7..757624cf 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -143,6 +143,16 @@ struct sc_pkcs15_prkey_dsa { sc_pkcs15_bignum_t priv; }; +struct sc_pkcs15_pubkey_gostr3410 { + sc_pkcs15_bignum_t x; + sc_pkcs15_bignum_t y; +}; + +struct sc_pkcs15_prkey_gostr3410 { + /* private components */ + sc_pkcs15_bignum_t d; +}; + struct sc_pkcs15_pubkey { int algorithm; @@ -150,6 +160,7 @@ struct sc_pkcs15_pubkey { union { struct sc_pkcs15_pubkey_rsa rsa; struct sc_pkcs15_pubkey_dsa dsa; + struct sc_pkcs15_pubkey_gostr3410 gostr3410; } u; /* DER encoded raw key */ @@ -162,6 +173,7 @@ struct sc_pkcs15_prkey { union { struct sc_pkcs15_prkey_rsa rsa; struct sc_pkcs15_prkey_dsa dsa; + struct sc_pkcs15_prkey_gostr3410 gostr3410; } u; }; typedef struct sc_pkcs15_prkey sc_pkcs15_prkey_t; @@ -242,6 +254,17 @@ typedef struct sc_pkcs15_data_info sc_pkcs15_data_info_t; #define SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE 0x08 #define SC_PKCS15_PRKEY_ACCESS_LOCAL 0x10 +#define SC_PKCS15_PARAMSET_GOSTR3410_A 1 +#define SC_PKCS15_PARAMSET_GOSTR3410_B 2 +#define SC_PKCS15_PARAMSET_GOSTR3410_C 3 + +#define SC_PKCS15_GOSTR3410_KEYSIZE 256 + +struct sc_pkcs15_keyinfo_gostparams +{ + unsigned int gostr3410, gostr3411, gost28147; +}; + struct sc_pkcs15_prkey_info { struct sc_pkcs15_id id; /* correlates to public certificate id */ unsigned int usage, access_flags; @@ -249,6 +272,8 @@ struct sc_pkcs15_prkey_info { size_t modulus_length; u8 *subject; size_t subject_len; + void *params; + size_t params_len; struct sc_path path; }; @@ -261,6 +286,8 @@ struct sc_pkcs15_pubkey_info { size_t modulus_length; u8 *subject; size_t subject_len; + void *params; + size_t params_len; struct sc_path path; }; @@ -271,10 +298,12 @@ typedef struct sc_pkcs15_pubkey_info sc_pkcs15_pubkey_info_t; #define SC_PKCS15_TYPE_PRKEY 0x100 #define SC_PKCS15_TYPE_PRKEY_RSA 0x101 #define SC_PKCS15_TYPE_PRKEY_DSA 0x102 +#define SC_PKCS15_TYPE_PRKEY_GOSTR3410 0x103 #define SC_PKCS15_TYPE_PUBKEY 0x200 #define SC_PKCS15_TYPE_PUBKEY_RSA 0x201 #define SC_PKCS15_TYPE_PUBKEY_DSA 0x202 +#define SC_PKCS15_TYPE_PUBKEY_GOSTR3410 0x203 #define SC_PKCS15_TYPE_CERT 0x400 #define SC_PKCS15_TYPE_CERT_X509 0x401 diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 6ee7200f..1b6ad9d0 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -105,8 +105,8 @@ struct pkcs15_pubkey_object { #define pub_cert base.related_cert #define __p15_type(obj) (((obj) && (obj)->p15_object)? ((obj)->p15_object->type) : (unsigned int)-1) -#define is_privkey(obj) (__p15_type(obj) == SC_PKCS15_TYPE_PRKEY_RSA) -#define is_pubkey(obj) (__p15_type(obj) == SC_PKCS15_TYPE_PUBKEY_RSA) +#define is_privkey(obj) (__p15_type(obj) == SC_PKCS15_TYPE_PRKEY_RSA || __p15_type(obj) == SC_PKCS15_TYPE_PRKEY_GOSTR3410) +#define is_pubkey(obj) (__p15_type(obj) == SC_PKCS15_TYPE_PUBKEY_RSA || __p15_type(obj) == SC_PKCS15_TYPE_PUBKEY_GOSTR3410) #define is_cert(obj) (__p15_type(obj) == SC_PKCS15_TYPE_CERT_X509) struct pkcs15_data_object { @@ -124,6 +124,18 @@ extern struct sc_pkcs11_object_ops pkcs15_prkey_ops; extern struct sc_pkcs11_object_ops pkcs15_pubkey_ops; extern struct sc_pkcs11_object_ops pkcs15_dobj_ops; +#define GOST_PARAMS_OID_SIZE 9 +static const struct { + const CK_BYTE oid[GOST_PARAMS_OID_SIZE]; + unsigned char param; +} gostr3410_param_oid [] = { + { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01 }, + SC_PKCS15_PARAMSET_GOSTR3410_A }, + { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02 }, + SC_PKCS15_PARAMSET_GOSTR3410_B }, + { { 0x06, 0x07, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03 }, + SC_PKCS15_PARAMSET_GOSTR3410_C } +}; static int __pkcs15_release_object(struct pkcs15_any_object *); static int register_mechanisms(struct sc_pkcs11_card *p11card); @@ -135,6 +147,7 @@ static CK_RV get_modulus_bits(struct sc_pkcs15_pubkey *, CK_ATTRIBUTE_PTR); static CK_RV get_usage_bit(unsigned int usage, CK_ATTRIBUTE_PTR attr); static CK_RV asn1_sequence_wrapper(const u8 *, size_t, CK_ATTRIBUTE_PTR); +static CK_RV get_gostr3410_params(const u8 *, size_t, CK_ATTRIBUTE_PTR); static void cache_pin(void *, int, const sc_path_t *, const void *, size_t); static int revalidate_pin(struct pkcs15_slot_data *data, struct sc_pkcs11_session *ses); @@ -275,7 +288,8 @@ static int public_key_created(struct pkcs15_fw_data *fw_data, } if ((fw_data->objects[ii]->p15_object->type != SC_PKCS15_TYPE_PUBKEY) && (fw_data->objects[ii]->p15_object->type != SC_PKCS15_TYPE_PUBKEY_RSA) && - (fw_data->objects[ii]->p15_object->type != SC_PKCS15_TYPE_PUBKEY_DSA)) { + (fw_data->objects[ii]->p15_object->type != SC_PKCS15_TYPE_PUBKEY_DSA) && + (fw_data->objects[ii]->p15_object->type != SC_PKCS15_TYPE_PUBKEY_GOSTR3410)) { ii++; continue; } @@ -637,6 +651,11 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL); break; + case SC_PKCS15_TYPE_PRKEY_GOSTR3410: + if (obj->related_cert == NULL) + pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); + pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL); + break; case SC_PKCS15_TYPE_CERT_X509: pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL); @@ -758,6 +777,20 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card) if (rv < 0) return sc_to_cryptoki_error(rv, reader); + rv = pkcs15_create_pkcs11_objects(fw_data, + SC_PKCS15_TYPE_PRKEY_GOSTR3410, + "private key", + __pkcs15_create_prkey_object); + if (rv < 0) + return sc_to_cryptoki_error(rv, reader); + + rv = pkcs15_create_pkcs11_objects(fw_data, + SC_PKCS15_TYPE_PUBKEY_GOSTR3410, + "public key", + __pkcs15_create_pubkey_object); + if (rv < 0) + return sc_to_cryptoki_error(rv, reader); + rv = pkcs15_create_pkcs11_objects(fw_data, SC_PKCS15_TYPE_CERT_X509, "certificate", @@ -1490,6 +1523,39 @@ get_X509_usage_pubk(CK_ATTRIBUTE_PTR pTempl, CK_ULONG ulCount, unsigned long *x5 return CKR_OK; } +static CK_RV +set_gost_params(struct sc_pkcs15init_prkeyargs *prkey_args, + struct sc_pkcs15init_pubkeyargs *pubkey_args, + CK_ATTRIBUTE_PTR pPubTpl, CK_ULONG ulPubCnt, + CK_ATTRIBUTE_PTR pPrivTpl, CK_ULONG ulPrivCnt) +{ + CK_BYTE gost_params_oid[GOST_PARAMS_OID_SIZE]; + size_t len, i; + CK_RV rv; + + len = GOST_PARAMS_OID_SIZE; + rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_GOSTR3410_PARAMS, + &gost_params_oid, &len); + if (rv == CKR_OK) { + if (len != GOST_PARAMS_OID_SIZE) + return CKR_ATTRIBUTE_VALUE_INVALID; + for (i = 0; i < sizeof(gostr3410_param_oid) + /sizeof(gostr3410_param_oid[0]); ++i) { + if (!memcmp(gost_params_oid, gostr3410_param_oid[i].oid, len)) { + prkey_args->gost_params.gostr3410 = + gostr3410_param_oid[i].param; + pubkey_args->gost_params.gostr3410 = + gostr3410_param_oid[i].param; + break; + } + } + if (i != sizeof(gostr3410_param_oid)/sizeof(gostr3410_param_oid[0])) + return CKR_OK; + return CKR_ATTRIBUTE_VALUE_INVALID; + } + return CKR_OK; +} + /* FIXME: check for the public exponent in public key template and use this value */ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *slot, @@ -1510,7 +1576,7 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, struct pkcs15_any_object *pub_any_obj; struct sc_pkcs15_id id; size_t len; - CK_KEY_TYPE keytype = CKK_RSA; + CK_KEY_TYPE keytype; CK_ULONG keybits; char pub_label[SC_PKCS15_MAX_LABEL_SIZE]; char priv_label[SC_PKCS15_MAX_LABEL_SIZE]; @@ -1518,7 +1584,8 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, sc_debug(context, "Keypair generation, mech = 0x%0x\n", pMechanism->mechanism); - if (pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN) + if (pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN + && pMechanism->mechanism != CKM_GOSTR3410_KEY_PAIR_GEN) return CKR_MECHANISM_INVALID; rc = sc_lock(p11card->card); @@ -1541,18 +1608,37 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_KEY_TYPE, &keytype, NULL); - if (rv == CKR_OK && keytype != CKK_RSA) { + if (rv != CKR_OK) + keytype = CKK_RSA; + if (keytype == CKK_GOSTR3410) + { + keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_GOSTR3410; + pub_args.key.algorithm = SC_ALGORITHM_GOSTR3410; + set_gost_params(&keygen_args.prkey_args, &pub_args, + pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt); + } + else if (keytype == CKK_RSA) + { + /* default value (CKA_KEY_TYPE isn't set) or CKK_RSA is set */ + keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_RSA; + pub_args.key.algorithm = SC_ALGORITHM_RSA; + } + else + { + /* CKA_KEY_TYPE is set, but keytype isn't correct */ rv = CKR_ATTRIBUTE_VALUE_INVALID; goto kpgen_done; } - keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_RSA; - pub_args.key.algorithm = SC_ALGORITHM_RSA; - - rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_MODULUS_BITS, - &keybits, NULL); - if (rv != CKR_OK) + if (keytype == CKK_GOSTR3410) + keybits = SC_PKCS15_GOSTR3410_KEYSIZE; + else if (keytype == CKK_RSA) + { + rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_MODULUS_BITS, + &keybits, NULL); + if (rv != CKR_OK) keybits = 1024; /* Default key size */ - /* To do: check allowed values of keybits */ + /* TODO: check allowed values of keybits */ + } id.len = SC_PKCS15_MAX_ID_SIZE; rv = attr_find2(pPubTpl, ulPubCnt, pPrivTpl, ulPrivCnt, CKA_ID, @@ -1995,7 +2081,10 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session, break; case CKA_KEY_TYPE: check_attribute_buffer(attr, sizeof(CK_KEY_TYPE)); - *(CK_KEY_TYPE*)attr->pValue = CKK_RSA; + if (key && key->algorithm == SC_ALGORITHM_GOSTR3410) + *(CK_KEY_TYPE*)attr->pValue = CKK_GOSTR3410; + else + *(CK_KEY_TYPE*)attr->pValue = CKK_RSA; break; case CKA_ID: check_attribute_buffer(attr, prkey->prv_info->id.len); @@ -2096,9 +2185,15 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj, case CKM_RSA_X_509: flags = SC_ALGORITHM_RSA_RAW; break; - case CKM_OPENSC_GOST: + case CKM_OPENSC_GOST: /* FIXME: */ flags = SC_ALGORITHM_GOST; break; + case CKM_GOSTR3410: + flags = SC_ALGORITHM_GOSTR3410_HASH_NONE; + break; + case CKM_GOSTR3410_WITH_GOSTR3411: + flags = SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411; + break; default: return CKR_MECHANISM_INVALID; } @@ -2347,7 +2442,10 @@ static CK_RV pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, break; case CKA_KEY_TYPE: check_attribute_buffer(attr, sizeof(CK_KEY_TYPE)); - *(CK_KEY_TYPE*)attr->pValue = CKK_RSA; + if (pubkey->pub_data && pubkey->pub_data->algorithm == SC_ALGORITHM_GOSTR3410) + *(CK_KEY_TYPE*)attr->pValue = CKK_GOSTR3410; + else + *(CK_KEY_TYPE*)attr->pValue = CKK_RSA; break; case CKA_ID: if (pubkey->pub_info) { @@ -2397,6 +2495,12 @@ static CK_RV pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, memcpy(attr->pValue, cert->cert_data->data, cert->cert_data->data_len); } break; + case CKA_GOSTR3410_PARAMS: + if (pubkey->pub_info && pubkey->pub_info->params_len) + return get_gostr3410_params(pubkey->pub_info->params, + pubkey->pub_info->params_len, attr); + else + return CKR_ATTRIBUTE_TYPE_INVALID; default: return CKR_ATTRIBUTE_TYPE_INVALID; } @@ -2671,6 +2775,26 @@ get_public_exponent(struct sc_pkcs15_pubkey *key, CK_ATTRIBUTE_PTR attr) return CKR_ATTRIBUTE_TYPE_INVALID; } +static CK_RV +get_gostr3410_params(const u8 *params, size_t params_len, CK_ATTRIBUTE_PTR attr) +{ + size_t i; + + if (!params || params_len == sizeof(int)) + return CKR_ATTRIBUTE_TYPE_INVALID; + + for (i = 0; i < sizeof(gostr3410_param_oid)/ + sizeof(gostr3410_param_oid[0]); ++i) { + if (gostr3410_param_oid[i].param == ((int*)params)[0]) { + check_attribute_buffer(attr, sizeof(gostr3410_param_oid[i].oid)); + memcpy(attr->pValue, gostr3410_param_oid[i].oid, + sizeof(gostr3410_param_oid[i].oid)); + return CKR_OK; + } + } + return CKR_ATTRIBUTE_TYPE_INVALID; +} + /* * Map pkcs15 usage bits to pkcs11 usage attributes. * @@ -2804,6 +2928,40 @@ revalidate_pin(struct pkcs15_slot_data *data, struct sc_pkcs11_session *ses) return rv; } +static int register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) +{ + CK_MECHANISM_INFO mech_info; + sc_pkcs11_mechanism_type_t *mt; + int rc; + + mech_info.flags = CKF_HW | CKF_SIGN | CKF_UNWRAP | CKF_DECRYPT; +#ifdef ENABLE_OPENSSL + mech_info.flags |= CKF_VERIFY; +#endif + mech_info.ulMinKeySize = SC_PKCS15_GOSTR3410_KEYSIZE; + mech_info.ulMaxKeySize = SC_PKCS15_GOSTR3410_KEYSIZE; + + if (flags & SC_ALGORITHM_GOSTR3410_HASH_NONE) { + mt = sc_pkcs11_new_fw_mechanism(CKM_GOSTR3410, + &mech_info, CKK_GOSTR3410, NULL); + if (!mt) + return CKR_HOST_MEMORY; + rc = sc_pkcs11_register_mechanism(p11card, mt); + if (rc != CKR_OK) + return rc; + } + if (flags & SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411) { + mt = sc_pkcs11_new_fw_mechanism(CKM_GOSTR3410_WITH_GOSTR3411, + &mech_info, CKK_GOSTR3410, NULL); + if (!mt) + return CKR_HOST_MEMORY; + rc = sc_pkcs11_register_mechanism(p11card, mt); + if (rc != CKR_OK) + return rc; + } + return CKR_OK; +} + /* * Mechanism handling * FIXME: We should consult the card's algorithm list to @@ -2843,7 +3001,9 @@ static int register_mechanisms(struct sc_pkcs11_card *p11card) flags |= alg_info->flags; } - + if (alg_info->algorithm == SC_ALGORITHM_GOSTR3410) + flags |= alg_info->flags; +#if 0 /* FIXME: */ if (alg_info->algorithm == SC_ALGORITHM_GOST){ mech_info.flags = CKF_HW | CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT; #ifdef ENABLE_OPENSSL @@ -2858,10 +3018,20 @@ static int register_mechanisms(struct sc_pkcs11_card *p11card) if(rc < 0) return rc; } - +#endif alg_info++; } + if (flags & (SC_ALGORITHM_GOSTR3410_RAW + | SC_ALGORITHM_GOSTR3410_HASH_NONE + | SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411)) { + if (flags & SC_ALGORITHM_GOSTR3410_RAW) + flags |= SC_ALGORITHM_GOSTR3410_HASH_NONE; + rc = register_gost_mechanisms(p11card, flags); + if (rc != CKR_OK) + return rc; + } + /* Check if we support raw RSA */ if (flags & SC_ALGORITHM_RSA_RAW) { mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, @@ -2906,7 +3076,6 @@ static int register_mechanisms(struct sc_pkcs11_card *p11card) sc_pkcs11_register_sign_and_hash_mechanism(p11card, CKM_XXX_RSA_PKCS, CKM_XXX, mt); #endif - #ifdef ENABLE_OPENSSL mech_info.flags = CKF_GENERATE_KEY_PAIR; mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS_KEY_PAIR_GEN, @@ -2916,7 +3085,6 @@ static int register_mechanisms(struct sc_pkcs11_card *p11card) return rc; #endif } - return CKR_OK; } diff --git a/src/pkcs11/mechanism.c b/src/pkcs11/mechanism.c index 99b9f912..5593f3e7 100644 --- a/src/pkcs11/mechanism.c +++ b/src/pkcs11/mechanism.c @@ -430,6 +430,8 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength) { struct sc_pkcs11_object *key; CK_ATTRIBUTE attr = { CKA_MODULUS_BITS, pLength, sizeof(*pLength) }; + CK_KEY_TYPE key_type; + CK_ATTRIBUTE attr_key_type = { CKA_KEY_TYPE, &key_type, sizeof(key_type) }; CK_RV rv; key = ((struct signature_data *) operation->priv_data)->key; @@ -439,6 +441,12 @@ sc_pkcs11_signature_size(sc_pkcs11_operation_t *operation, CK_ULONG_PTR pLength) if (rv == CKR_OK) *pLength = (*pLength + 7) / 8; + if (rv == CKR_OK) { + rv = key->ops->get_attribute(operation->session, key, &attr_key_type); + if (rv == CKR_OK && key_type == CKK_GOSTR3410) + *pLength *= 2; + } + return rv; } @@ -612,7 +620,11 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, struct signature_data *data; struct sc_pkcs11_object *key; unsigned char *pubkey_value; + CK_KEY_TYPE key_type; + CK_BYTE params[9 /* GOST_PARAMS_OID_SIZE */] = { 0 }; CK_ATTRIBUTE attr = {CKA_VALUE, NULL, 0}; + CK_ATTRIBUTE attr_key_type = {CKA_KEY_TYPE, &key_type, sizeof(key_type)}; + CK_ATTRIBUTE attr_key_params = {CKA_GOSTR3410_PARAMS, ¶ms, sizeof(params)}; int rv; data = (struct signature_data *) operation->priv_data; @@ -630,7 +642,15 @@ sc_pkcs11_verify_final(sc_pkcs11_operation_t *operation, if (rv != CKR_OK) goto done; + rv = key->ops->get_attribute(operation->session, key, &attr_key_type); + if (rv == CKR_OK && key_type == CKK_GOSTR3410) { + rv = key->ops->get_attribute(operation->session, key, &attr_key_params); + if (rv != CKR_OK) + goto done; + } + rv = sc_pkcs11_verify_data(pubkey_value, attr.ulValueLen, + params, sizeof(params), operation->mechanism.mechanism, data->md, data->buffer, data->buffer_len, pSignature, ulSignatureLen); diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 592d7630..e84e9b3e 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -13,6 +13,10 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#include +#include +#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */ static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *); static CK_RV sc_pkcs11_openssl_md_update(sc_pkcs11_operation_t *, @@ -63,6 +67,18 @@ static sc_pkcs11_mechanism_type_t openssl_sha512_mech = { }; #endif +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +static sc_pkcs11_mechanism_type_t openssl_gostr3411_mech = { + CKM_GOSTR3411, + { 0, 0, CKF_DIGEST }, 0, + sizeof(struct sc_pkcs11_operation), + sc_pkcs11_openssl_md_release, + sc_pkcs11_openssl_md_init, + sc_pkcs11_openssl_md_update, + sc_pkcs11_openssl_md_final +}; +#endif + static sc_pkcs11_mechanism_type_t openssl_md5_mech = { CKM_MD5, { 0, 0, CKF_DIGEST }, 0, @@ -86,6 +102,10 @@ static sc_pkcs11_mechanism_type_t openssl_ripemd160_mech = { void sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *card) { +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + /* FIXME: see openssl-1.0.0-beta3/engines/ccgost/README.gost */ + OPENSSL_config(NULL); +#endif openssl_sha1_mech.mech_data = EVP_sha1(); sc_pkcs11_register_mechanism(card, &openssl_sha1_mech); #if OPENSSL_VERSION_NUMBER >= 0x00908000L @@ -100,6 +120,10 @@ sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *card) sc_pkcs11_register_mechanism(card, &openssl_md5_mech); openssl_ripemd160_mech.mech_data = EVP_ripemd160(); sc_pkcs11_register_mechanism(card, &openssl_ripemd160_mech); +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + openssl_gostr3411_mech.mech_data = EVP_get_digestbynid(NID_id_GostR3411_94); + sc_pkcs11_register_mechanism(card, &openssl_gostr3411_mech); +#endif } @@ -224,11 +248,94 @@ sc_pkcs11_gen_keypair_soft(CK_KEY_TYPE keytype, CK_ULONG keybits, return CKR_OK; } +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + +static void reverse(unsigned char *buf, size_t len) +{ + unsigned char tmp; + size_t i; + + for (i = 0; i < len / 2; ++i) { + tmp = buf[i]; + buf[i] = buf[len - 1 - i]; + buf[len - 1 - i] = tmp; + } +} + +static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len, + const unsigned char *params, int params_len, + unsigned char *data, int data_len, + unsigned char *signat, int signat_len) +{ + EVP_PKEY *pkey; + EVP_PKEY_CTX *pkey_ctx; + EC_POINT *P; + BIGNUM *X, *Y; + const EC_GROUP *group = NULL; + char paramset[2] = "A"; + int r = -1, ret_vrf = 0; + + pkey = EVP_PKEY_new(); + if (!pkey) + return CKR_HOST_MEMORY; + r = EVP_PKEY_set_type(pkey, NID_id_GostR3410_2001); + if (r == 1) { + pkey_ctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkey_ctx) { + EVP_PKEY_free(pkey); + return CKR_HOST_MEMORY; + } + /* FIXME: fully check params[] */ + if (params_len > 0 && params[params_len - 1] >= 1 && + params[params_len - 1] <= 3) { + paramset[0] += params[params_len - 1] - 1; + r = EVP_PKEY_CTX_ctrl_str(pkey_ctx, "paramset", paramset); + } + else + r = -1; + if (r == 1) + r = EVP_PKEY_paramgen_init(pkey_ctx); + if (r == 1) + r = EVP_PKEY_paramgen(pkey_ctx, &pkey); + if (r == 1 && EVP_PKEY_get0(pkey) != NULL) + group = EC_KEY_get0_group(EVP_PKEY_get0(pkey)); + r = -1; + if (group && pubkey_len == 0x20 + 0x20 + 4 + 2) { + X = BN_bin2bn(pubkey + 4, 0x20, NULL); + Y = BN_bin2bn(pubkey + 4 + 2 + 0x20, 0x20, NULL); + + P = EC_POINT_new(group); + if (P && X && Y) + r = EC_POINT_set_affine_coordinates_GFp(group, + P, X, Y, NULL); + BN_free(X); + BN_free(Y); + if (r == 1 && EVP_PKEY_get0(pkey) && P) + r = EC_KEY_set_public_key(EVP_PKEY_get0(pkey), P); + EC_POINT_free(P); + } + if (r == 1) { + r = EVP_PKEY_verify_init(pkey_ctx); + reverse(data, data_len); + if (r == 1) + ret_vrf = EVP_PKEY_verify(pkey_ctx, signat, signat_len, + data, data_len); + } + } + EVP_PKEY_CTX_free(pkey_ctx); + EVP_PKEY_free(pkey); + if (r != 1) + return CKR_GENERAL_ERROR; + return ret_vrf == 1 ? CKR_OK : CKR_SIGNATURE_INVALID; +} +#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */ + /* If no hash function was used, finish with RSA_public_decrypt(). * If a hash function was used, we can make a big shortcut by * finishing with EVP_VerifyFinal(). */ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, + const unsigned char *pubkey_params, int pubkey_params_len, CK_MECHANISM_TYPE mech, sc_pkcs11_operation_t *md, unsigned char *data, int data_len, unsigned char *signat, int signat_len) @@ -237,10 +344,20 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, CK_RV rv = CKR_GENERAL_ERROR; EVP_PKEY *pkey; + if (mech == CKM_GOSTR3410) + { +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + return gostr3410_verify_data(pubkey, pubkey_len, + pubkey_params, pubkey_params_len, + data, data_len, signat, signat_len); +#else + return CKR_FUNCTION_NOT_SUPPORTED; +#endif + } + pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &pubkey, pubkey_len); if (pkey == NULL) return CKR_GENERAL_ERROR; - if (md != NULL) { EVP_MD_CTX *md_ctx = DIGEST_CTX(md); diff --git a/src/pkcs11/pkcs11.h b/src/pkcs11/pkcs11.h index d5bc2c64..03e904b7 100644 --- a/src/pkcs11/pkcs11.h +++ b/src/pkcs11/pkcs11.h @@ -356,6 +356,7 @@ typedef unsigned long ck_key_type_t; #define CKK_AES (0x1fUL) #define CKK_BLOWFISH (0x20UL) #define CKK_TWOFISH (0x21UL) +#define CKK_GOSTR3410 (0x30UL) #define CKK_VENDOR_DEFINED (1UL << 31) @@ -433,6 +434,9 @@ typedef unsigned long ck_attribute_type_t; #define CKA_AUTH_PIN_FLAGS (0x201UL) #define CKA_ALWAYS_AUTHENTICATE (0x202UL) #define CKA_WRAP_WITH_TRUSTED (0x210UL) +#define CKA_GOSTR3410_PARAMS (0x250UL) +#define CKA_GOSTR3411_PARAMS (0x251UL) +#define CKA_GOST28147_PARAMS (0x252UL) #define CKA_HW_FEATURE_TYPE (0x300UL) #define CKA_RESET_ON_INIT (0x301UL) #define CKA_HAS_RESET (0x302UL) @@ -669,6 +673,10 @@ typedef unsigned long ck_mechanism_type_t; #define CKM_AES_MAC (0x1083UL) #define CKM_AES_MAC_GENERAL (0x1084UL) #define CKM_AES_CBC_PAD (0x1085UL) +#define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL) +#define CKM_GOSTR3410 (0x1201UL) +#define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) +#define CKM_GOSTR3411 (0x1210UL) #define CKM_DSA_PARAMETER_GEN (0x2000UL) #define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) #define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 1ab197e9..d511808e 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -440,6 +440,7 @@ CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *, CK_RV sc_pkcs11_gen_keypair_soft(CK_KEY_TYPE keytype, CK_ULONG keybits, struct sc_pkcs15_prkey *privkey, struct sc_pkcs15_pubkey *pubkey); CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, + const unsigned char *pubkey_params, int pubkey_params_len, CK_MECHANISM_TYPE mech, sc_pkcs11_operation_t *md, unsigned char *inp, int inp_len, unsigned char *signat, int signat_len); diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index 2319d1a4..f993937d 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -219,6 +219,10 @@ struct sc_pkcs15init_pinargs { size_t puk_len; }; +struct sc_pkcs15init_keyarg_gost_params { + unsigned char gostr3410, gostr3411, gost28147; +}; + struct sc_pkcs15init_prkeyargs { struct sc_pkcs15_id id; struct sc_pkcs15_id auth_id; @@ -226,6 +230,7 @@ struct sc_pkcs15init_prkeyargs { unsigned long usage; unsigned long x509_usage; unsigned int flags; + struct sc_pkcs15init_keyarg_gost_params gost_params; sc_pkcs15_prkey_t key; @@ -248,6 +253,7 @@ struct sc_pkcs15init_pubkeyargs { const char * label; unsigned long usage; unsigned long x509_usage; + struct sc_pkcs15init_keyarg_gost_params gost_params; sc_pkcs15_pubkey_t key; }; diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index 87e3f53f..de65352e 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -1172,6 +1172,7 @@ sc_pkcs15init_init_prkdf(sc_pkcs15_card_t *p15card, ) { struct sc_pkcs15_prkey_info *key_info; + struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; struct sc_pkcs15_object *object; sc_card_t *card = p15card->card; const char *label; @@ -1238,6 +1239,19 @@ sc_pkcs15init_init_prkdf(sc_pkcs15_card_t *p15card, key_info->id = keyargs->id; + if (key->algorithm == SC_ALGORITHM_GOSTR3410) { + key_info->params_len = sizeof(*keyinfo_gostparams); + /* FIXME: malloc() call in pkcs15init, but free() call + * in libopensc (sc_pkcs15_free_prkey_info) */ + key_info->params = malloc(key_info->params_len); + if (!key_info->params) + return SC_ERROR_OUT_OF_MEMORY; + keyinfo_gostparams = key_info->params; + keyinfo_gostparams->gostr3410 = keyargs->gost_params.gostr3410; + keyinfo_gostparams->gostr3411 = keyargs->gost_params.gostr3411; + keyinfo_gostparams->gost28147 = keyargs->gost_params.gost28147; + } + r = select_object_path(p15card, profile, object, &key_info->id, &key_info->path); if (r < 0) @@ -1295,7 +1309,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, if (r != SC_SUCCESS) return r; - /* For now, we support just RSA key pair generation */ + /* For now, we support just RSA and GOST key pair generation */ if (!check_key_compatibility(p15card, &keygen_args->prkey_args.key, keygen_args->prkey_args.x509_usage, keybits, SC_ALGORITHM_ONBOARD_KEY_GEN)) @@ -1331,6 +1345,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, pubkey_args.label = keygen_args->pubkey_label; pubkey_args.usage = keygen_args->prkey_args.usage; pubkey_args.x509_usage = keygen_args->prkey_args.x509_usage; + pubkey_args.gost_params = keygen_args->prkey_args.gost_params; /* Generate the private key on card */ if (profile->ops->create_key) { @@ -1572,6 +1587,7 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, { struct sc_pkcs15_object *object; struct sc_pkcs15_pubkey_info *key_info; + struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams; sc_pkcs15_pubkey_t key; sc_pkcs15_der_t der_encoded; sc_path_t *path; @@ -1594,6 +1610,9 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, keybits = sc_pkcs15init_keybits(&key.u.dsa.q); type = SC_PKCS15_TYPE_PUBKEY_DSA; break; #endif + case SC_ALGORITHM_GOSTR3410: + keybits = SC_PKCS15_GOSTR3410_KEYSIZE; + type = SC_PKCS15_TYPE_PUBKEY_GOSTR3410; break; default: sc_debug(p15card->card->ctx, "Unsupported key algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; @@ -1617,6 +1636,19 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, key_info->usage = usage; key_info->modulus_length = keybits; + if (key.algorithm == SC_ALGORITHM_GOSTR3410) { + key_info->params_len = sizeof(*keyinfo_gostparams); + /* FIXME: malloc() call in pkcs15init, but free() call + * in libopensc (sc_pkcs15_free_prkey_info) */ + key_info->params = malloc(key_info->params_len); + if (!key_info->params) + return SC_ERROR_OUT_OF_MEMORY; + keyinfo_gostparams = key_info->params; + keyinfo_gostparams->gostr3410 = keyargs->gost_params.gostr3410; + keyinfo_gostparams->gostr3411 = keyargs->gost_params.gostr3411; + keyinfo_gostparams->gost28147 = keyargs->gost_params.gost28147; + } + /* Select a Key ID if the user didn't specify one, otherwise * make sure it's unique */ *res_obj = NULL; @@ -2162,6 +2194,7 @@ prkey_fixup(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_t *key) case SC_ALGORITHM_RSA: return prkey_fixup_rsa(p15card, &key->u.rsa); case SC_ALGORITHM_DSA: + case SC_ALGORITHM_GOSTR3410: /* for now */ return 0; } @@ -2176,6 +2209,14 @@ prkey_bits(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_t *key) return sc_pkcs15init_keybits(&key->u.rsa.modulus); case SC_ALGORITHM_DSA: return sc_pkcs15init_keybits(&key->u.dsa.q); + case SC_ALGORITHM_GOSTR3410: + if (sc_pkcs15init_keybits(&key->u.gostr3410.d) + > SC_PKCS15_GOSTR3410_KEYSIZE) { + sc_debug(p15card->card->ctx, "Unsupported key (keybits %u)\n", + sc_pkcs15init_keybits(&key->u.gostr3410.d)); + return SC_ERROR_OBJECT_NOT_VALID; + } + return SC_PKCS15_GOSTR3410_KEYSIZE; } sc_debug(p15card->card->ctx, "Unsupported key algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; @@ -2189,6 +2230,8 @@ prkey_pkcs15_algo(sc_pkcs15_card_t *p15card, sc_pkcs15_prkey_t *key) return SC_PKCS15_TYPE_PRKEY_RSA; case SC_ALGORITHM_DSA: return SC_PKCS15_TYPE_PRKEY_DSA; + case SC_ALGORITHM_GOSTR3410: + return SC_PKCS15_TYPE_PRKEY_GOSTR3410; } sc_debug(p15card->card->ctx, "Unsupported key algorithm.\n"); return SC_ERROR_NOT_SUPPORTED; diff --git a/src/pkcs15init/pkcs15-rtecp.c b/src/pkcs15init/pkcs15-rtecp.c index 7172dae3..42672892 100644 --- a/src/pkcs15init/pkcs15-rtecp.c +++ b/src/pkcs15init/pkcs15-rtecp.c @@ -245,10 +245,14 @@ static int rtecp_create_key(sc_profile_t *profile, sc_card_t *card, * RSA_PUBkey Rabin test Attempts Reserve */ const unsigned char prkey_prop[] = { 0x23, 0x1F, 0, 0xFF, 0, 0 }; const unsigned char pbkey_prop[] = { 0x33, 0x1F, 0, 0xFF, 0, 0 }; + /* GOSTR3410_PRkey/ + * GOSTR3410_PUBkey paramset Attempts Reserve */ + unsigned char prgkey_prop[] = { 0x03, '?', 0, 0xFF, 0, 0 }; + unsigned char pbgkey_prop[] = { 0x13, '?', 0, 0xFF, 0, 0 }; /* AccessMode - Update Use - - - Delete */ unsigned char prkey_sec[15] = { 0x46, 0, '?', '?', 0, 0, 0, '?' }; unsigned char pbkey_sec[15] = { 0x46, 0, '?', 0, 0, 0, 0, '?' }; - unsigned char auth_id; + unsigned char auth_id, paramset; sc_pkcs15_prkey_info_t *key_info; sc_file_t *file; int r; @@ -257,7 +261,8 @@ static int rtecp_create_key(sc_profile_t *profile, sc_card_t *card, return SC_ERROR_INVALID_ARGUMENTS; SC_FUNC_CALLED(card->ctx, 1); - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) + if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA + && obj->type != SC_PKCS15_TYPE_PRKEY_GOSTR3410) return SC_ERROR_NOT_SUPPORTED; if (obj->auth_id.len != 1) return SC_ERROR_INVALID_ARGUMENTS; @@ -265,12 +270,29 @@ static int rtecp_create_key(sc_profile_t *profile, sc_card_t *card, key_info = (sc_pkcs15_prkey_info_t *)obj->data; assert(key_info); - if (key_info->modulus_length % 128 != 0) + if ((obj->type == SC_PKCS15_TYPE_PRKEY_RSA + && key_info->modulus_length % 128 != 0) + || (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410 + && key_info->modulus_length + != SC_PKCS15_GOSTR3410_KEYSIZE)) { sc_debug(card->ctx, "Unsupported key size %u\n", key_info->modulus_length); return SC_ERROR_INVALID_ARGUMENTS; } + if (obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) + { + if (key_info->params_len < sizeof(int)) + return SC_ERROR_INVALID_ARGUMENTS; + if (((int*)key_info->params)[0] < 1 + || ((int*)key_info->params)[0] > 3) + return SC_ERROR_INVALID_ARGUMENTS; + paramset = ((unsigned int*)key_info->params)[0] & 0x03; + assert(sizeof(prgkey_prop)/sizeof(prgkey_prop[0]) > 1); + assert(sizeof(pbgkey_prop)/sizeof(pbgkey_prop[0]) > 1); + prgkey_prop[1] = 0x10 + (paramset << 4); + pbgkey_prop[1] = prgkey_prop[1]; + } r = sc_profile_get_file(profile, "PKCS15-AppDF", &file); SC_TEST_RET(card->ctx, r, "Get PKCS15-AppDF info failed"); @@ -287,7 +309,10 @@ static int rtecp_create_key(sc_profile_t *profile, sc_card_t *card, file->id = key_info->key_reference; r = sc_file_set_type_attr(file, (const u8*)"\x10\x00", 2); /* private key file */ - file->size = key_info->modulus_length / 8 / 2 * 5 + 8; + if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) + file->size = key_info->modulus_length / 8 / 2 * 5 + 8; + else + file->size = key_info->modulus_length / 8; if (r == SC_SUCCESS) { assert(sizeof(prkey_sec)/sizeof(prkey_sec[0]) > 7); @@ -297,11 +322,19 @@ static int rtecp_create_key(sc_profile_t *profile, sc_card_t *card, r = sc_file_set_sec_attr(file, prkey_sec, sizeof(prkey_sec)); } if (r == SC_SUCCESS) - r = sc_file_set_prop_attr(file, prkey_prop, sizeof(prkey_prop)); + { + if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) + r = sc_file_set_prop_attr(file, prkey_prop, sizeof(prkey_prop)); + else + r = sc_file_set_prop_attr(file, prgkey_prop,sizeof(prgkey_prop)); + } if (r == SC_SUCCESS) r = sc_create_file(card, file); /* public key file */ - file->size = key_info->modulus_length / 8 / 2 * 3; + if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) + file->size = key_info->modulus_length / 8 / 2 * 3; + else + file->size = key_info->modulus_length / 8 * 2; if (r == SC_SUCCESS) { assert(sizeof(pbkey_sec)/sizeof(pbkey_sec[0]) > 7); @@ -310,7 +343,12 @@ static int rtecp_create_key(sc_profile_t *profile, sc_card_t *card, r = sc_file_set_sec_attr(file, pbkey_sec, sizeof(pbkey_sec)); } if (r == SC_SUCCESS) - r = sc_file_set_prop_attr(file, pbkey_prop, sizeof(pbkey_prop)); + { + if (obj->type == SC_PKCS15_TYPE_PRKEY_RSA) + r = sc_file_set_prop_attr(file, pbkey_prop, sizeof(pbkey_prop)); + else + r = sc_file_set_prop_attr(file, pbgkey_prop,sizeof(pbgkey_prop)); + } if (r == SC_SUCCESS) r = sc_create_file(card, file); assert(file); @@ -328,72 +366,98 @@ static int rtecp_store_key(sc_profile_t *profile, sc_card_t *card, sc_file_t *pukey_df; sc_path_t path; unsigned char *buf; - size_t len, i; + size_t buf_len, key_len, len, i; int r; if (!profile || !card || !card->ctx || !obj || !obj->data || !key) return SC_ERROR_INVALID_ARGUMENTS; SC_FUNC_CALLED(card->ctx, 1); - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) + if ((obj->type != SC_PKCS15_TYPE_PRKEY_RSA || key->algorithm != SC_ALGORITHM_RSA) + && (obj->type != SC_PKCS15_TYPE_PRKEY_GOSTR3410 + || key->algorithm != SC_ALGORITHM_GOSTR3410)) return SC_ERROR_NOT_SUPPORTED; key_info = (sc_pkcs15_prkey_info_t *)obj->data; assert(key_info); - assert(key_info->modulus_length % 128 == 0); - len = key_info->modulus_length / 8 / 2; - if (!key->u.rsa.p.data || !key->u.rsa.q.data || !key->u.rsa.iqmp.data + if (key->algorithm == SC_ALGORITHM_RSA) + { + assert(key_info->modulus_length % 128 == 0); + len = key_info->modulus_length / 8 / 2; + key_len = len * 5 + 8; + buf_len = key_len; + } + else + { + assert(key_info->modulus_length == SC_PKCS15_GOSTR3410_KEYSIZE); + len = key_info->modulus_length / 8; + key_len = len; + buf_len = len; + } + if (key->algorithm == SC_ALGORITHM_RSA && (!key->u.rsa.p.data + || !key->u.rsa.q.data || !key->u.rsa.iqmp.data || !key->u.rsa.dmp1.data || !key->u.rsa.dmq1.data || !key->u.rsa.modulus.data || !key->u.rsa.exponent.data || key->u.rsa.p.len != len || key->u.rsa.q.len != len || key->u.rsa.iqmp.len != len || key->u.rsa.dmp1.len != len || key->u.rsa.dmq1.len != len || key->u.rsa.modulus.len != 2*len - || key->u.rsa.exponent.len > len || key->u.rsa.exponent.len == 0) + || key->u.rsa.exponent.len > len || key->u.rsa.exponent.len == 0)) return SC_ERROR_INVALID_ARGUMENTS; - - buf = calloc(1, len * 5 + 8); + if (key->algorithm == SC_ALGORITHM_GOSTR3410 && (!key->u.gostr3410.d.data + || key->u.gostr3410.d.len != len)) + return SC_ERROR_INVALID_ARGUMENTS; + buf = calloc(1, buf_len); if (!buf) SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_OUT_OF_MEMORY); - assert(key->u.rsa.p.data && key->u.rsa.q.data && key->u.rsa.iqmp.data - && key->u.rsa.dmp1.data && key->u.rsa.dmq1.data - && key->u.rsa.p.len == len && key->u.rsa.q.len == len - && key->u.rsa.iqmp.len == len - && key->u.rsa.dmp1.len == len - && key->u.rsa.dmq1.len == len); - /* p */ - for (i = 0; i < len; ++i) - buf[i] = key->u.rsa.p.data[len - 1 - i]; - /* q */ - for (i = 0; i < len; ++i) - buf[len + 4 + i] = key->u.rsa.q.data[len - 1 - i]; - /* iqmp */ - for (i = 0; i < len; ++i) - buf[len + 4 + len + 4 + i] = key->u.rsa.iqmp.data[len - 1 - i]; - /* dmp1 */ - for (i = 0; i < len; ++i) - buf[len + 4 + len + 4 + len + i] = key->u.rsa.dmp1.data[len - 1 - i]; - /* dmq1 */ - for (i = 0; i < len; ++i) - buf[len * 4 + 8 + i] = key->u.rsa.dmq1.data[len - 1 - i]; - + assert(key_len <= buf_len); + if (key->algorithm == SC_ALGORITHM_RSA) + { + /* p */ + for (i = 0; i < len; ++i) + buf[i] = key->u.rsa.p.data[len - 1 - i]; + /* q */ + for (i = 0; i < len; ++i) + buf[len + 4 + i] = key->u.rsa.q.data[len - 1 - i]; + /* iqmp */ + for (i = 0; i < len; ++i) + buf[len + 4 + len + 4 + i] = key->u.rsa.iqmp.data[len - 1 - i]; + /* dmp1 */ + for (i = 0; i < len; ++i) + buf[len + 4 + len + 4 + len + i] = + key->u.rsa.dmp1.data[len - 1 - i]; + /* dmq1 */ + for (i = 0; i < len; ++i) + buf[len * 4 + 8 + i] = key->u.rsa.dmq1.data[len - 1 - i]; + } + else + { + /* d */ + for (i = 0; i < len; ++i) + buf[i] = key->u.gostr3410.d.data[len - 1 - i]; + } path = key_info->path; r = sc_select_file(card, &path, NULL); if (r == SC_SUCCESS) - r = sc_change_reference_data(card, 0, 0, NULL, 0, buf, len*5 + 8, NULL); + r = sc_change_reference_data(card, 0, 0, NULL, 0, buf, key_len, NULL); assert(buf); - sc_mem_clear(buf, len * 5 + 8); + sc_mem_clear(buf, key_len); /* store public key */ - assert(key->u.rsa.modulus.data && key->u.rsa.exponent.data - && key->u.rsa.modulus.len == 2*len - && key->u.rsa.exponent.len <= len - && key->u.rsa.exponent.len > 0); - /* modulus */ - for (i = 0; i < 2*len; ++i) - buf[i] = key->u.rsa.modulus.data[2*len - 1 - i]; - /* exponent */ - for (i = 0; i < key->u.rsa.exponent.len && i < len; ++i) - buf[2*len+i] = key->u.rsa.exponent.data[key->u.rsa.exponent.len - 1 - i]; + if (key->algorithm == SC_ALGORITHM_RSA) + key_len = len * 3; + else + goto end; + assert(key_len <= buf_len); + if (key->algorithm == SC_ALGORITHM_RSA) + { + /* modulus */ + for (i = 0; i < 2*len; ++i) + buf[i] = key->u.rsa.modulus.data[2*len - 1 - i]; + /* exponent */ + for (i = 0; i < key->u.rsa.exponent.len && i < len; ++i) + buf[2 * len + i] = key->u.rsa.exponent.data[ + key->u.rsa.exponent.len - 1 - i]; + } if (r == SC_SUCCESS) { r = sc_profile_get_file(profile, "PuKey-DF", &pukey_df); @@ -412,10 +476,11 @@ static int rtecp_store_key(sc_profile_t *profile, sc_card_t *card, r = sc_select_file(card, &path, NULL); if (r == SC_SUCCESS) r = sc_change_reference_data(card, 0, 0, NULL, 0, - buf, len*3, NULL); + buf, key_len, NULL); if (r && card->ctx->debug >= 2) sc_debug(card->ctx, "%s\n", "Store public key failed"); } +end: assert(buf); free(buf); SC_FUNC_RETURN(card->ctx, 1, r); @@ -435,33 +500,72 @@ static int rtecp_generate_key(sc_profile_t *profile, sc_card_t *card, return SC_ERROR_INVALID_ARGUMENTS; SC_FUNC_CALLED(card->ctx, 1); - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) + switch (obj->type) + { + case SC_PKCS15_TYPE_PRKEY_RSA: + data.type = SC_ALGORITHM_RSA; + break; + case SC_PKCS15_TYPE_PRKEY_GOSTR3410: + data.type = SC_ALGORITHM_GOSTR3410; + break; + default: return SC_ERROR_NOT_SUPPORTED; - + } key_info = (sc_pkcs15_prkey_info_t *)obj->data; assert(key_info); data.key_id = key_info->key_reference; assert(data.key_id != 0); - assert(key_info->modulus_length % 128 == 0); - data.modulus_len = key_info->modulus_length / 8; - data.modulus = calloc(1, data.modulus_len); - data.exponent_len = key_info->modulus_length / 8 / 2; - data.exponent = calloc(1, data.exponent_len); - if (!data.modulus || !data.exponent) + switch (data.type) { - free(data.modulus); - free(data.exponent); - SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_OUT_OF_MEMORY); + case SC_ALGORITHM_RSA: + assert(key_info->modulus_length % 128 == 0); + data.u.rsa.modulus_len = key_info->modulus_length / 8; + data.u.rsa.modulus = calloc(1, data.u.rsa.modulus_len); + data.u.rsa.exponent_len = key_info->modulus_length / 8 / 2; + data.u.rsa.exponent = calloc(1, data.u.rsa.exponent_len); + if (!data.u.rsa.modulus || !data.u.rsa.exponent) + { + free(data.u.rsa.modulus); + free(data.u.rsa.exponent); + SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_OUT_OF_MEMORY); + } + break; + case SC_ALGORITHM_GOSTR3410: + assert(key_info->modulus_length == SC_PKCS15_GOSTR3410_KEYSIZE); + data.u.gostr3410.x_len = key_info->modulus_length / 8; + data.u.gostr3410.x = calloc(1, data.u.gostr3410.x_len); + data.u.gostr3410.y_len = key_info->modulus_length / 8; + data.u.gostr3410.y = calloc(1, data.u.gostr3410.y_len); + if (!data.u.gostr3410.x || !data.u.gostr3410.y) + { + free(data.u.gostr3410.x); + free(data.u.gostr3410.y); + SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_OUT_OF_MEMORY); + } + break; + default: + assert(0); } r = sc_card_ctl(card, SC_CARDCTL_RTECP_GENERATE_KEY, &data); if (r == SC_SUCCESS) { assert(pubkey); - pubkey->algorithm = SC_ALGORITHM_RSA; - pubkey->u.rsa.modulus.data = data.modulus; - pubkey->u.rsa.modulus.len = data.modulus_len; - pubkey->u.rsa.exponent.data = data.exponent; - pubkey->u.rsa.exponent.len = data.exponent_len; + pubkey->algorithm = data.type; + switch (data.type) + { + case SC_ALGORITHM_RSA: + pubkey->u.rsa.modulus.data = data.u.rsa.modulus; + pubkey->u.rsa.modulus.len = data.u.rsa.modulus_len; + pubkey->u.rsa.exponent.data = data.u.rsa.exponent; + pubkey->u.rsa.exponent.len = data.u.rsa.exponent_len; + break; + case SC_ALGORITHM_GOSTR3410: + pubkey->u.gostr3410.x.data = data.u.gostr3410.x; + pubkey->u.gostr3410.x.len = data.u.gostr3410.x_len; + pubkey->u.gostr3410.y.data = data.u.gostr3410.y; + pubkey->u.gostr3410.y.len = data.u.gostr3410.y_len; + break; + } } SC_FUNC_RETURN(card->ctx, 1, r); } From 615b1814713d9de8f1f92bb88f63cee422c30584 Mon Sep 17 00:00:00 2001 From: martin Date: Mon, 12 Oct 2009 09:26:05 +0000 Subject: [PATCH 32/57] Revert [3752] git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3773 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/apdu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libopensc/apdu.c b/src/libopensc/apdu.c index e63e207a..2101f22e 100644 --- a/src/libopensc/apdu.c +++ b/src/libopensc/apdu.c @@ -300,15 +300,15 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu) goto error; break; case SC_APDU_CASE_3_SHORT: - /* inconsistent datalen */ - if (apdu->datalen != apdu->lc) - goto error; /* data is sent */ - if (apdu->datalen != 0 && apdu->data == NULL) + if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0) goto error; /* no data is expected */ if (apdu->le != 0) goto error; + /* inconsistent datalen */ + if (apdu->datalen != apdu->lc) + goto error; break; case SC_APDU_CASE_4_SHORT: /* data is sent */ From 4196e9f15633ecc6ca3a5b4979b222c5d8b06d2a Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 13 Oct 2009 08:29:29 +0000 Subject: [PATCH 33/57] PC/SC: Log enabled options. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3774 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/reader-pcsc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 1f302a65..5fc33e73 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -693,6 +693,8 @@ static int pcsc_init(sc_context_t *ctx, void **reader_data) gpriv->provider_library = scconf_get_str(conf_block, "provider_library", gpriv->provider_library); } + sc_debug(ctx, "PC/SC options: connect_reset=%d connect_exclusive=%d transaction_reset=%d enable_pinpad=%d", + gpriv->connect_reset, gpriv->connect_exclusive, gpriv->transaction_reset, gpriv->enable_pinpad); gpriv->dlhandle = lt_dlopen(gpriv->provider_library); if (gpriv->dlhandle == NULL) { From 95a5ab065401968c7f300ee4bd8d391d96279013 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 22 Oct 2009 08:59:59 +0000 Subject: [PATCH 34/57] Re-implement PIN cache on PKCS#15 layer; remove it from PKCS#11. Re-name and log PKCS#15 options to better reflect the purpose. Data objects and PKCS#15 init are left broken currently. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3784 c6295689-39f2-0310-b995-f0e70906c6a9 --- configure.ac | 2 +- etc/opensc.conf.in | 27 ++++--- src/libopensc/libopensc.exports | 1 + src/libopensc/opensc.h | 1 + src/libopensc/pkcs15-actalis.c | 2 +- src/libopensc/pkcs15-infocamere.c | 2 +- src/libopensc/pkcs15-pin.c | 103 +++++++++++++++++++++++- src/libopensc/pkcs15-sec.c | 8 ++ src/libopensc/pkcs15.c | 32 ++++---- src/libopensc/pkcs15.h | 14 +++- src/libopensc/sc.c | 21 +++++ src/pkcs11/framework-pkcs15.c | 125 ++---------------------------- src/pkcs11/misc.c | 6 +- src/pkcs11/sc-pkcs11.h | 1 - src/tools/pkcs15-tool.c | 2 +- 15 files changed, 188 insertions(+), 159 deletions(-) diff --git a/configure.ac b/configure.ac index 7d30cbaa..ef1c60b1 100644 --- a/configure.ac +++ b/configure.ac @@ -300,7 +300,7 @@ AC_HEADER_SYS_WAIT AC_CHECK_HEADERS([ \ errno.h fcntl.h malloc.h stdlib.h \ inttypes.h string.h strings.h \ - sys/time.h unistd.h locale.h getopt.h + sys/time.h unistd.h locale.h getopt.h sys/mman.h ]) dnl Checks for typedefs, structures, and compiler characteristics. diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in index 3eb0899e..a4259812 100644 --- a/etc/opensc.conf.in +++ b/etc/opensc.conf.in @@ -248,14 +248,25 @@ app default { # WARNING: Caching shouldn't be used in setuid root # applications. # Default: false + # use_file_caching = true; + # + # Use PIN caching? + # Default: true + # use_pin_caching = false; + # + # How many times to use a PIN from cache before re-authenticating it? + # Default: 10 + # pin_cache_counter = 3; # - use_caching = true; # Enable pkcs15 emulation. # Default: yes # enable_pkcs15_emulation = no; # # Prefer pkcs15 emulation code before # the normal pkcs15 processing. + # Some cards (like esteid and pteid) work in emu-only mode, + # and do not depend on this option. + # # Default: no # try_emulation_first = yes; # @@ -285,7 +296,7 @@ app default { # so you can turn it off, if it misbehaves. # this option only affects cardos cards right now. # Default: yes - # enable_sign_with_decrypt_workaround = yes; + # enable_sign_with_decrypt_workaround = no; } } @@ -345,19 +356,7 @@ app opensc-pkcs11 { # # Default: true # lock_login = false; - - # Normally, the pkcs11 module will not cache PINs - # presented via C_Login. However, some cards - # may not work properly with OpenSC; for instance - # when you have two keys on your card that get - # stored in two different directories. # - # In this case, you can turn on PIN caching by setting - # cache_pins = true - # - # Default: true - # cache_pins = false; - # Set this value to true if you want to allow off-card # keypair generation (in software on your pc) # diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index 7276210b..af3d7ade 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -156,6 +156,7 @@ sc_pkcs15_make_absolute_path sc_pkcs15_parse_df sc_pkcs15_parse_tokeninfo sc_pkcs15_parse_unusedspace +sc_pkcs15_pincache_clear sc_pkcs15_print_id sc_pkcs15_read_cached_file sc_pkcs15_read_certificate diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 0b91564b..0aab3660 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -1144,6 +1144,7 @@ int sc_base64_decode(const char *in, u8 *out, size_t outlen); * @param len length of the memory buffer */ void sc_mem_clear(void *ptr, size_t len); +void *sc_mem_alloc_secure(size_t len); int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize); int sc_make_cache_dir(sc_context_t *ctx); diff --git a/src/libopensc/pkcs15-actalis.c b/src/libopensc/pkcs15-actalis.c index db60ce05..83eda5fb 100644 --- a/src/libopensc/pkcs15-actalis.c +++ b/src/libopensc/pkcs15-actalis.c @@ -177,7 +177,7 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card) const char *authPRKEY = "Authentication Key"; /* const char *nonrepPRKEY = "Non repudiation Key"; */ - p15card->opts.use_cache = 1; + p15card->opts.use_file_cache = 1; /* Get Serial number */ sc_format_path("3F0030000001", &path); diff --git a/src/libopensc/pkcs15-infocamere.c b/src/libopensc/pkcs15-infocamere.c index f9d2a40c..12643141 100644 --- a/src/libopensc/pkcs15-infocamere.c +++ b/src/libopensc/pkcs15-infocamere.c @@ -590,7 +590,7 @@ static int infocamere_1400_init(sc_pkcs15_card_t * p15card) set_security_env = card->ops->set_security_env; card->ops->set_security_env = infocamere_1400_set_sec_env; card->ops->compute_signature = do_sign; - p15card->opts.use_cache = 1; + p15card->opts.use_file_cache = 1; sc_format_path("30000001", &path); diff --git a/src/libopensc/pkcs15-pin.c b/src/libopensc/pkcs15-pin.c index 2b9c629d..5b2b19d3 100644 --- a/src/libopensc/pkcs15-pin.c +++ b/src/libopensc/pkcs15-pin.c @@ -51,6 +51,8 @@ static const struct sc_asn1_entry c_asn1_pin[] = { { NULL, 0, 0, 0, NULL, NULL } }; +static void sc_pkcs15_pincache_add(struct sc_pkcs15_card *p15card, struct sc_pkcs15_pin_info *pininfo, const u8 *pin, size_t pinlen); + int sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj, const u8 ** buf, size_t *buflen) @@ -198,15 +200,13 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, sc_card_t *card; struct sc_pin_cmd_data data; + SC_FUNC_CALLED(p15card->card->ctx, 2); if ((r = _validate_pin(p15card, pin, pinlen)) != SC_SUCCESS) return r; card = p15card->card; r = sc_lock(card); - if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) { - r = sc_lock(card); - } SC_TEST_RET(card->ctx, r, "sc_lock() failed"); /* the path in the pin object is optional */ if (pin->path.len > 0) { @@ -251,6 +251,8 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, } r = sc_pin_cmd(card, &data, &pin->tries_left); + if (r == SC_SUCCESS) + sc_pkcs15_pincache_add(p15card, pin, pincode, pinlen); out: sc_unlock(card); return r; @@ -328,6 +330,8 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card, } r = sc_pin_cmd(card, &data, &pin->tries_left); + if (r == SC_SUCCESS) + sc_pkcs15_pincache_add(p15card, pin, newpin, newpinlen); out: sc_unlock(card); @@ -436,6 +440,8 @@ int sc_pkcs15_unblock_pin(struct sc_pkcs15_card *p15card, } r = sc_pin_cmd(card, &data, &pin->tries_left); + if (r == SC_SUCCESS) + sc_pkcs15_pincache_add(p15card, pin, newpin, newpinlen); out: sc_unlock(card); @@ -446,3 +452,94 @@ void sc_pkcs15_free_pin_info(sc_pkcs15_pin_info_t *pin) { free(pin); } + +/* Add a PIN to the PIN cache related to the card. Some operations can trigger re-authentication later. */ +static void sc_pkcs15_pincache_add(struct sc_pkcs15_card *p15card, + struct sc_pkcs15_pin_info *pininfo, + const u8 *pin, size_t pinlen) +{ + int i; + sc_pkcs15_pincache_entry_t *entry; + sc_pkcs15_object_t *obj; + + SC_FUNC_CALLED(p15card->card->ctx, 2); + + if (!p15card->opts.use_pin_cache) + return; + + /* Is it a user consent protecting PIN ? */ + if (sc_pkcs15_find_prkey_by_reference(p15card, NULL, pininfo->reference, &obj) == SC_SUCCESS) { + if (obj->user_consent) { + sc_debug(p15card->card->ctx, "Not caching userconsent related PIN"); + return; + } + } + + for (i=0; ipin_cache[i] == NULL) { + entry = (sc_pkcs15_pincache_entry_t *) sc_mem_alloc_secure(sizeof(sc_pkcs15_pincache_entry_t)); + if (!entry) + return; + memcpy(&entry->id, &pininfo->auth_id, sizeof(sc_pkcs15_id_t)); + memcpy(&entry->pin, pin, pinlen); + entry->len = pinlen; + entry->counter = 0; + p15card->pin_cache[i] = entry; + return; + } else { /* Update the existing PIN */ + sc_pkcs15_pincache_entry_t *entry = p15card->pin_cache[i]; + if (sc_pkcs15_compare_id(&entry->id, &pininfo->auth_id)) { + memcpy(&entry->pin, pin, pinlen); + entry->len = pinlen; + entry->counter = 0; + return; + } + + } + } +} +/* Validate the PIN code associated with an object */ +int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_object_t *obj) +{ + int r, i; + sc_pkcs15_object_t *pin_obj; + sc_pkcs15_pin_info_t *pin_info; + + SC_FUNC_CALLED(p15card->card->ctx, 2); + + if (!p15card->opts.use_pin_cache) + return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; + + if (obj->user_consent) + return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; + + if (p15card->card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) + return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; + + r = sc_pkcs15_find_pin_by_auth_id(p15card, &obj->auth_id, &pin_obj); + if (r != SC_SUCCESS) { + sc_debug(p15card->card->ctx, "Could not find pin object for auth_id %s", sc_pkcs15_print_id(&obj->auth_id)); + return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; + } + + pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data; + for (i=0; ipin_cache[i] != NULL; i++) { + sc_pkcs15_pincache_entry_t *entry = p15card->pin_cache[i]; + if (sc_pkcs15_compare_id(&entry->id, &obj->auth_id)) { + if (entry->counter >= p15card->opts.pin_cache_counter) { + sc_mem_clear(entry->pin, entry->len); + return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; + } + entry->counter++; + return sc_pkcs15_verify_pin(p15card, pin_info, entry->pin, entry->len); + } + } + return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; +} + +void sc_pkcs15_pincache_clear(struct sc_pkcs15_card *p15card) +{ + int i; + for (i=0; ipin_cache[i] != NULL; i++) + sc_mem_clear(p15card->pin_cache[i]->pin, p15card->pin_cache[i]->len); +} \ No newline at end of file diff --git a/src/libopensc/pkcs15-sec.c b/src/libopensc/pkcs15-sec.c index 69246265..cc8eadb9 100644 --- a/src/libopensc/pkcs15-sec.c +++ b/src/libopensc/pkcs15-sec.c @@ -121,6 +121,10 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card, SC_TEST_RET(ctx, r, "sc_set_security_env() failed"); } r = sc_decipher(p15card->card, in, inlen, out, outlen); + if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { + if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS) + r = sc_decipher(p15card->card, in, inlen, out, outlen); + } sc_unlock(p15card->card); SC_TEST_RET(ctx, r, "sc_decipher() failed"); @@ -268,6 +272,10 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, } r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen); + if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { + if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS) + r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen); + } sc_mem_clear(buf, sizeof(buf)); sc_unlock(p15card->card); SC_TEST_RET(ctx, r, "sc_compute_signature() failed"); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 7292893e..9188ec8e 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -416,6 +416,8 @@ struct sc_pkcs15_card * sc_pkcs15_card_new(void) void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card) { + size_t i; + if (p15card == NULL) return; assert(p15card->magic == SC_PKCS15_CARD_MAGIC); @@ -446,11 +448,14 @@ void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card) if (p15card->preferred_language != NULL) free(p15card->preferred_language); if (p15card->seInfo != NULL) { - size_t i; for (i = 0; i < p15card->num_seInfo; i++) free(p15card->seInfo[i]); free(p15card->seInfo); } + for (i=0; ipin_cache[i] != NULL; i++) { + sc_mem_clear(p15card->pin_cache[i]->pin, p15card->pin_cache[i]->len); + free(p15card->pin_cache[i]); + } free(p15card); } @@ -567,8 +572,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card) goto end; if (p15card->file_odf == NULL) { - /* check if an ODF is present; suppress errors as we - * don't know yet whether we have a pkcs15 card */ + /* check if an ODF is present; we don't know yet whether we have a pkcs15 card */ tmppath = p15card->file_app->path; sc_append_path_id(&tmppath, (const u8 *) "\x50\x31", 2); err = sc_select_file(card, &tmppath, &p15card->file_odf); @@ -697,19 +701,21 @@ int sc_pkcs15_bind(sc_card_t *card, p15card = sc_pkcs15_card_new(); if (p15card == NULL) return SC_ERROR_OUT_OF_MEMORY; - p15card->card = card; - for (i = 0; ctx->conf_blocks[i] != NULL; i++) { - blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], - "framework", "pkcs15"); - if (blocks && blocks[0] != NULL) - conf_block = blocks[0]; - free(blocks); - } + p15card->card = card; + p15card->opts.use_file_cache = 0; + p15card->opts.use_pin_cache = 1; + p15card->opts.pin_cache_counter = 10; + + conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1); if (conf_block) { - p15card->opts.use_cache = scconf_get_bool(conf_block, "use_caching", 0); + p15card->opts.use_file_cache = scconf_get_bool(conf_block, "use_file_caching", p15card->opts.use_file_cache); + p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache); + p15card->opts.pin_cache_counter = scconf_get_bool(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter); } + sc_debug(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d", + p15card->opts.use_file_cache, p15card->opts.use_pin_cache, p15card->opts.pin_cache_counter); r = sc_lock(card); if (r) { @@ -1676,7 +1682,7 @@ int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, } r = -1; /* file state: not in cache */ - if (p15card->opts.use_cache) { + if (p15card->opts.use_file_cache) { r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len); } if (r) { diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 757624cf..1ab2c3a6 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -380,6 +380,13 @@ typedef struct { size_t aid_len; } sc_pkcs15_sec_env_info_t; +typedef struct { + sc_pkcs15_id_t id; + u8 pin[SC_MAX_PIN_SIZE]; + size_t len; + int counter; +} sc_pkcs15_pincache_entry_t; + typedef struct { unsigned int version; unsigned int flags; @@ -412,11 +419,14 @@ typedef struct sc_pkcs15_card { int unusedspace_read; struct sc_pkcs15_card_opts { - int use_cache; + int use_file_cache; + int use_pin_cache; + int pin_cache_counter; } opts; sc_pkcs15_sec_env_info_t **seInfo; size_t num_seInfo; + sc_pkcs15_pincache_entry_t *pin_cache[SC_PKCS15_MAX_PINS]; unsigned int magic; @@ -561,6 +571,8 @@ int sc_pkcs15_find_pin_by_reference(struct sc_pkcs15_card *card, struct sc_pkcs15_object **out); int sc_pkcs15_find_so_pin(struct sc_pkcs15_card *card, struct sc_pkcs15_object **out); +int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_object_t *obj); +void sc_pkcs15_pincache_clear(struct sc_pkcs15_card *p15card); int sc_pkcs15_encode_dir(struct sc_context *ctx, struct sc_pkcs15_card *card, diff --git a/src/libopensc/sc.c b/src/libopensc/sc.c index 500a64b3..083ea944 100644 --- a/src/libopensc/sc.c +++ b/src/libopensc/sc.c @@ -26,6 +26,9 @@ #include /* for OPENSSL_cleanse */ #endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif #include "internal.h" #include #include @@ -715,6 +718,24 @@ int _sc_parse_atr(sc_context_t *ctx, sc_slot_info_t *slot) return 0; } +void *sc_mem_alloc_secure(size_t len) +{ + void *pointer; + + pointer = calloc(len, sizeof(unsigned char)); + if (!pointer) + return NULL; +#ifdef HAVE_SYS_MMAN_H + /* TODO Windows support and mprotect too */ + /* Do not swap the memory */ + if (mlock(pointer, len) == -1) { + free(pointer); + return NULL; + } +#endif + return pointer; +} + void sc_mem_clear(void *ptr, size_t len) { #ifdef ENABLE_OPENSSL diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 1b6ad9d0..dd31be62 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -28,15 +28,8 @@ extern int hack_enabled; -#define MAX_CACHE_PIN 32 struct pkcs15_slot_data { struct sc_pkcs15_object *auth_obj; - int user_consent; - struct { - sc_path_t path; - u8 value[MAX_CACHE_PIN]; - unsigned int len; - } pin[2]; }; #define slot_data(p) ((struct pkcs15_slot_data *) (p)) #define slot_data_auth(p) (slot_data(p)->auth_obj) @@ -148,9 +141,6 @@ static CK_RV get_modulus_bits(struct sc_pkcs15_pubkey *, static CK_RV get_usage_bit(unsigned int usage, CK_ATTRIBUTE_PTR attr); static CK_RV asn1_sequence_wrapper(const u8 *, size_t, CK_ATTRIBUTE_PTR); static CK_RV get_gostr3410_params(const u8 *, size_t, CK_ATTRIBUTE_PTR); -static void cache_pin(void *, int, const sc_path_t *, const void *, size_t); -static int revalidate_pin(struct pkcs15_slot_data *data, - struct sc_pkcs11_session *ses); static int lock_card(struct pkcs15_fw_data *); static int unlock_card(struct pkcs15_fw_data *); static void add_pins_to_keycache(struct sc_pkcs11_card *p11card, @@ -634,11 +624,6 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, obj->base.flags |= SC_PKCS11_OBJECT_SEEN; obj->refcount++; - if (obj->p15_object && (obj->p15_object->user_consent > 0) ) { - sc_debug(context, "User consent object detected, marking slot as user_consent!\n"); - ((struct pkcs15_slot_data *)slot->fw_data)->user_consent = 1; - } - /* Add related objects * XXX prevent infinite recursion when a card specifies two certificates * referring to each other. @@ -679,7 +664,6 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *card, slot->token_info.flags |= CKF_USER_PIN_INITIALIZED; if (card->card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) { slot->token_info.flags |= CKF_PROTECTED_AUTHENTICATION_PATH; - sc_pkcs11_conf.cache_pins = 0; } if (card->card->caps & SC_CARD_CAP_RNG) slot->token_info.flags |= CKF_RNG; @@ -970,10 +954,6 @@ static CK_RV pkcs15_login(struct sc_pkcs11_card *p11card, rc = sc_pkcs15_verify_pin(card, pin, pPin, ulPinLen); sc_debug(context, "PIN verification returned %d\n", rc); - - if (rc >= 0) - cache_pin(fw_token, userType, &pin->path, pPin, ulPinLen); - return sc_to_cryptoki_error(rc, p11card->reader); } @@ -981,10 +961,8 @@ static CK_RV pkcs15_logout(struct sc_pkcs11_card *p11card, void *fw_token) { struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data; int rc = 0; - - cache_pin(fw_token, CKU_SO, NULL, NULL, 0); - cache_pin(fw_token, CKU_USER, NULL, NULL, 0); - + + sc_pkcs15_pincache_clear(fw_data->p15_card); sc_logout(fw_data->p15_card->card); if (sc_pkcs11_conf.lock_login) @@ -1021,9 +999,6 @@ static CK_RV pkcs15_change_pin(struct sc_pkcs11_card *p11card, rc = sc_pkcs15_change_pin(fw_data->p15_card, pin, pOldPin, ulOldLen, pNewPin, ulNewLen); sc_debug(context, "PIN change returned %d\n", rc); - - if (rc >= 0) - cache_pin(fw_token, CKU_USER, &pin->path, pNewPin, ulNewLen); return sc_to_cryptoki_error(rc, p11card->reader); } @@ -1069,9 +1044,6 @@ static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card, pkcs15_init_slot(fw_data->p15_card, slot, auth_obj); pin_info = (sc_pkcs15_pin_info_t *) auth_obj->data; - - cache_pin(slot->fw_data, CKU_USER, &pin_info->path, pPin, ulPinLen); - return CKR_OK; } @@ -2219,15 +2191,6 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj, pSignature, *pulDataLen); - /* Do we have to try a re-login and then try to sign again? */ - if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { - rv = revalidate_pin(data, ses); - if (rv == 0) - rv = sc_pkcs15_compute_signature(fw_data->p15_card, - prkey->prv_p15obj, flags, pData, ulDataLen, - pSignature, *pulDataLen); - } - sc_unlock(ses->slot->card->card); sc_debug(context, "Sign complete. Result %d.\n", rv); @@ -2294,14 +2257,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj, flags, pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted)); - /* Do we have to try a re-login and then try to decrypt again? */ - if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { - rv = revalidate_pin(data, ses); - if (rv == 0) - rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, - flags, pEncryptedData, ulEncryptedDataLen, - decrypted, sizeof(decrypted)); - } sc_unlock(ses->slot->card->card); sc_debug(context, "Key unwrap/decryption complete. Result %d.\n", rv); @@ -2557,13 +2512,6 @@ static int pkcs15_dobj_get_value(struct sc_pkcs11_session *session, rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, out_data); - /* Do we have to try a re-login and then try to sign again? */ - if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { - rv = revalidate_pin(data, session); - if (rv == 0) - rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, out_data); - } - sc_unlock(card); if (rv < 0) return sc_to_cryptoki_error(rv, reader); @@ -2684,13 +2632,6 @@ static CK_RV pkcs15_dobj_destroy(struct sc_pkcs11_session *session, void *object /* Delete object in smartcard */ rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object); - /* Do we have to try a re-login and then try to delete again? */ - if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { - rv = revalidate_pin(data, session); - if (rv == 0) - rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object); - } - sc_pkcs15init_unbind(profile); sc_unlock(card->card); @@ -2870,64 +2811,6 @@ asn1_sequence_wrapper(const u8 *data, size_t len, CK_ATTRIBUTE_PTR attr) return CKR_OK; } -static void -cache_pin(void *p, int user, const sc_path_t *path, const void *pin, size_t len) -{ - struct pkcs15_slot_data *data = (struct pkcs15_slot_data *) p; - -#ifdef USE_PKCS15_INIT - if (len == 0) { - sc_keycache_forget_key(path, SC_AC_SYMBOLIC, - user? SC_PKCS15INIT_USER_PIN : SC_PKCS15INIT_SO_PIN); - } -#endif - - if ((user != CKU_SO && user != CKU_USER) || !sc_pkcs11_conf.cache_pins) - return; - /* Don't cache pins related to user_consent objects/slots */ - if (data->user_consent) - return; - - memset(&data->pin[user], 0, sizeof(data->pin[user])); - if (len && len <= MAX_CACHE_PIN) { - memcpy(data->pin[user].value, pin, len); - data->pin[user].len = len; - if (path) - data->pin[user].path = *path; - } -} - -/* TODO: GUI must indicate pinpad revalidation instead of a plain error.*/ -static int -revalidate_pin(struct pkcs15_slot_data *data, struct sc_pkcs11_session *ses) -{ - int rv; - u8 value[MAX_CACHE_PIN]; - - sc_debug(context, "PIN revalidation\n"); - - if (!sc_pkcs11_conf.cache_pins - && !(ses->slot->token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH)) - return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; - - if (sc_pkcs11_conf.cache_pins && data->user_consent) - return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED; - - if (ses->slot->token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) { - rv = pkcs15_login(ses->slot->card, ses->slot->fw_data, CKU_USER, NULL, 0); - } - else { - memcpy(value, data->pin[CKU_USER].value, data->pin[CKU_USER].len); - rv = pkcs15_login(ses->slot->card, ses->slot->fw_data, CKU_USER, - value, data->pin[CKU_USER].len); - } - - if (rv != CKR_OK) - sc_debug(context, "Re-login failed: 0x%0x (%d)\n", rv, rv); - - return rv; -} - static int register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags) { CK_MECHANISM_INFO mech_info; @@ -3085,6 +2968,7 @@ static int register_mechanisms(struct sc_pkcs11_card *p11card) return rc; #endif } + return CKR_OK; } @@ -3116,7 +3000,8 @@ static void add_pins_to_keycache(struct sc_pkcs11_card *p11card, struct sc_pkcs11_slot *slot) { -#ifdef USE_PKCS15_INIT +#if 0 +//#ifdef USE_PKCS15_INIT struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data; struct sc_pkcs15_card *p15card = fw_data->p15_card; struct pkcs15_slot_data *p15_data = slot_data(slot->fw_data); diff --git a/src/pkcs11/misc.c b/src/pkcs11/misc.c index 69c2136b..d208b8f8 100644 --- a/src/pkcs11/misc.c +++ b/src/pkcs11/misc.c @@ -322,8 +322,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t *ctx) conf->max_virtual_slots = 16; conf->slots_per_card = 4; conf->hide_empty_tokens = 1; - conf->lock_login = 1; - conf->cache_pins = 1; + conf->lock_login = 0; conf->soft_keygen_allowed = 0; @@ -339,6 +338,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t *ctx) conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card); conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens); conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login); - conf->cache_pins = scconf_get_bool(conf_block, "cache_pins", conf->cache_pins); conf->soft_keygen_allowed = scconf_get_bool(conf_block, "soft_keygen_allowed", conf->soft_keygen_allowed); + sc_debug(ctx, "PKCS#11 options: plug_and_play=%d max_virtual_slots=%d slots_per_card=%d hide_empty_tokens=%d lock_login=%d", + conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card, conf->hide_empty_tokens, conf->lock_login); } diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index d511808e..2b85bec6 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -92,7 +92,6 @@ struct sc_pkcs11_config { unsigned int slots_per_card; unsigned char hide_empty_tokens; unsigned char lock_login; - unsigned char cache_pins; unsigned char soft_keygen_allowed; }; diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index f0de198d..431c8d50 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -1541,7 +1541,7 @@ int main(int argc, char * const argv[]) goto end; } if (opt_no_cache) - p15card->opts.use_cache = 0; + p15card->opts.use_file_cache = 0; if (verbose) fprintf(stderr, "Found %s!\n", p15card->label); if (do_learn_card) { From 56fb57603b58117e2acc94b51328941e1eb635e5 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 22 Oct 2009 09:18:16 +0000 Subject: [PATCH 35/57] Merge [3758:3783/trunk] git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3785 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/Makefile.mak | 3 +- src/libopensc/card-entersafe.c | 2 +- src/libopensc/card-myeid.c | 5 +- src/libopensc/card-piv.c | 12 +-- src/libopensc/card-rutoken.c | 8 -- src/libopensc/card-tcos.c | 5 +- src/libopensc/card-westcos.c | 154 ++++++-------------------- src/libopensc/cardctl.h | 2 +- src/libopensc/muscle.c | 5 +- src/libopensc/muscle.h | 2 +- src/libopensc/opensc.h | 9 -- src/libopensc/pkcs15-esinit.c | 4 +- src/libopensc/reader-pcsc.c | 4 + src/pkcs11/framework-pkcs15.c | 184 +++++++++++++++++++------------- src/pkcs11/pkcs11-global.c | 5 +- src/pkcs11/pkcs11-opensc.h | 4 - src/pkcs15init/keycache.c | 4 - src/pkcs15init/pkcs15-cardos.c | 4 +- src/pkcs15init/pkcs15-myeid.c | 5 +- src/pkcs15init/pkcs15-westcos.c | 118 ++++++-------------- src/pkcs15init/rutoken.profile | 5 +- src/tools/opensc-explorer.c | 2 +- src/tools/pkcs11-tool.c | 1 - src/tools/util.c | 2 +- src/tools/westcos-tool.c | 36 +++++-- 25 files changed, 227 insertions(+), 358 deletions(-) diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak index 43f65b1f..c7b06c6d 100644 --- a/src/libopensc/Makefile.mak +++ b/src/libopensc/Makefile.mak @@ -22,14 +22,13 @@ OBJECTS = \ \ ctbcs.obj reader-ctapi.obj reader-pcsc.obj reader-openct.obj \ \ - card-westcos.obj crc_AetB.obj \ card-setcos.obj card-miocos.obj card-flex.obj card-gpk.obj \ card-cardos.obj card-tcos.obj card-emv.obj card-default.obj \ card-mcrd.obj card-starcos.obj card-openpgp.obj card-jcop.obj \ card-oberthur.obj card-belpic.obj card-atrust-acos.obj card-entersafe.obj \ card-incrypto34.obj card-piv.obj card-muscle.obj card-acos5.obj \ card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \ - card-rtecp.obj card-myeid.obj card-ias.obj \ + card-rtecp.obj card-westcos.obj card-myeid.obj card-ias.obj \ \ p15emu-westcos.obj \ pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \ diff --git a/src/libopensc/card-entersafe.c b/src/libopensc/card-entersafe.c index 92a1d792..7d7e67f0 100644 --- a/src/libopensc/card-entersafe.c +++ b/src/libopensc/card-entersafe.c @@ -538,7 +538,7 @@ static int entersafe_select_path(sc_card_t *card, const u8 *path=pathbuf; size_t pathlen=len; int bMatch = -1; - int i; + unsigned int i; int r; if (pathlen%2 != 0 || pathlen > 6 || pathlen <= 0) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 162a7327..c622d479 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -40,7 +40,8 @@ static struct sc_card_operations myeid_ops; static struct sc_card_driver myeid_drv = { "MyEID cards with PKCS#15 applet", "myeid", - &myeid_ops + &myeid_ops, + NULL, 0, NULL }; static const char *myeid_atrs[] = { @@ -202,7 +203,7 @@ static int myeid_read_binary(struct sc_card *card, unsigned int idx, static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen) { struct sc_apdu apdu; - int r,i; + int r; sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0xA1); apdu.resp = buf; diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 94565aef..790e2887 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -887,8 +887,6 @@ static int piv_cache_internal_data(sc_card_t *card, int enumtag) priv->obj_cache[enumtag].internal_obj_data, priv->obj_cache[enumtag].internal_obj_len); - -ok: SC_FUNC_RETURN(card->ctx, 1, 0); } @@ -906,8 +904,6 @@ static int piv_read_binary(sc_card_t *card, unsigned int idx, int r; u8 *rbuf = NULL; size_t rbuflen = 0; - u8 *tag; - size_t taglen; u8 *body; size_t bodylen; @@ -950,11 +946,6 @@ static int piv_read_binary(sc_card_t *card, unsigned int idx, if (r < 0) goto err; } - if (tag == NULL) { - r = SC_ERROR_OBJECT_NOT_VALID; - goto err; - } - } priv->rb_state = 0; @@ -1101,7 +1092,7 @@ static int piv_get_3des_key(sc_card_t *card, u8 *key) int r; int f = -1; - char keybuf[24*3-1]; /* 3des key as three sets of xx:xx:xx:xx:xx:xx:xx:xx + char keybuf[24*3]; /* 3des key as three sets of xx:xx:xx:xx:xx:xx:xx:xx * with a : between which is 71 bytes */ char * keyfilename = NULL; size_t outlen; @@ -1128,6 +1119,7 @@ static int piv_get_3des_key(sc_card_t *card, u8 *key) } keybuf[23] = '\0'; keybuf[47] = '\0'; + keybuf[71] = '\0'; outlen = 8; r = sc_hex_to_bin(keybuf, key, &outlen); if (r) goto err; diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index 5d1fcc8c..af1e8025 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -138,7 +138,6 @@ static int rutoken_match_card(sc_card_t *card) static int token_init(sc_card_t *card, const char *card_name) { unsigned int flags; - sc_algorithm_info_t info; SC_FUNC_CALLED(card->ctx, 3); @@ -155,13 +154,6 @@ static int token_init(sc_card_t *card, const char *card_name) _sc_card_add_rsa_alg(card, 1024, flags, 0); _sc_card_add_rsa_alg(card, 2048, flags, 0); - memset(&info, 0, sizeof(info)); - info.algorithm = SC_ALGORITHM_GOST; - info.flags = SC_ALGORITHM_GOST_CRYPT_PZ | SC_ALGORITHM_GOST_CRYPT_GAMM - | SC_ALGORITHM_GOST_CRYPT_GAMMOS; - info.key_length = 32; - _sc_card_add_algorithm(card, &info); - SC_FUNC_RETURN(card->ctx, 3, SC_SUCCESS); } diff --git a/src/libopensc/card-tcos.c b/src/libopensc/card-tcos.c index fc0e50fb..dca3c5f1 100644 --- a/src/libopensc/card-tcos.c +++ b/src/libopensc/card-tcos.c @@ -337,7 +337,8 @@ static int tcos_select_file(sc_card_t *card, sc_apdu_t apdu; sc_file_t *file=NULL; u8 buf[SC_MAX_APDU_BUFFER_SIZE], pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; - int i, r, pathlen; + unsigned int i; + int r, pathlen; assert(card != NULL && in_path != NULL); ctx=card->ctx; @@ -653,7 +654,7 @@ static int tcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_len, if (apdu.sw1==0x90 && apdu.sw2==0x00) { size_t len= (apdu.resplen>outlen) ? outlen : apdu.resplen; - int offset=0; + unsigned int offset=0; if(tcos3 && (data->pad_flags & SC_ALGORITHM_RSA_PAD_PKCS1) && apdu.resp[0]==0 && apdu.resp[1]==2){ offset=2; while(offset(b))?(a):(b)) -#endif - #define DEFAULT_TRANSPORT_KEY "6f:59:b0:ed:6e:62:46:4a:5d:25:37:68:23:a8:a2:2d" #define JAVACARD (0x01) @@ -50,7 +46,7 @@ #ifdef ENABLE_OPENSSL #define DEBUG_SSL #ifdef DEBUG_SSL -static void print_openssl_erreur(void) +static void print_openssl_error(void) { static int charge = 0; long r; @@ -276,100 +272,11 @@ static int westcos_init(sc_card_t * card) static int westcos_select_file(sc_card_t * card, const sc_path_t * in_path, sc_file_t ** file_out) { - sc_context_t *ctx; - sc_apdu_t apdu; - u8 buf[SC_MAX_APDU_BUFFER_SIZE]; - u8 pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf; - int r, pathlen; - sc_file_t *file = NULL; - priv_data_t *priv_data = NULL; - if (card->ctx->debug >= 1) - sc_debug(card->ctx, "westcos_select_file\n"); - if (card == NULL) - return SC_ERROR_INVALID_ARGUMENTS; - priv_data = (priv_data_t *) card->drv_data; - priv_data->file_id = 0; - ctx = card->ctx; - memcpy(path, in_path->value, in_path->len); - pathlen = (int)in_path->len; - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0); - switch (in_path->type) { - case SC_PATH_TYPE_FILE_ID: - apdu.p1 = 0; - if (pathlen != 2) - return SC_ERROR_INVALID_ARGUMENTS; - break; - case SC_PATH_TYPE_DF_NAME: - apdu.p1 = 4; - break; - case SC_PATH_TYPE_PATH: - apdu.p1 = 9; - if (pathlen == 2 && memcmp(path, "\x3F\x00", 2) == 0) { - apdu.p1 = 0; - } + priv_data_t *priv_data = (priv_data_t *) card->drv_data; - else if (pathlen > 2 && memcmp(path, "\x3F\x00", 2) == 0) { - apdu.p1 = 8; - pathlen -= 2; - memcpy(path, &in_path->value[2], pathlen); - } - break; - case SC_PATH_TYPE_FROM_CURRENT: - apdu.p1 = 9; - break; - case SC_PATH_TYPE_PARENT: - apdu.p1 = 3; - pathlen = 0; - apdu.cse = SC_APDU_CASE_3_SHORT; - break; - default: - return SC_ERROR_INVALID_ARGUMENTS; - } - apdu.p2 = 0; /* first record, return FCI */ - apdu.lc = pathlen; - apdu.data = path; - apdu.datalen = pathlen; - if (file_out != NULL) { - apdu.resp = buf; - apdu.resplen = sizeof(buf); - apdu.le = 255; - } else { - apdu.resplen = 0; - apdu.le = 0; - apdu.cse = SC_APDU_CASE_3_SHORT; - } - r = sc_transmit_apdu(card, &apdu); - if (r) - return (r); - if (file_out == NULL) { - if (apdu.sw1 == 0x61) - return 0; - return sc_check_sw(card, apdu.sw1, apdu.sw2); - } - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r) - return (r); - switch (apdu.resp[0]) { - case 0x6F: - file = sc_file_new(); - if (file == NULL) - return SC_ERROR_OUT_OF_MEMORY; - file->path = *in_path; - if (card->ops->process_fci == NULL) { - sc_file_free(file); - return SC_ERROR_NOT_SUPPORTED; - } - if (apdu.resp[1] <= apdu.resplen) - card->ops->process_fci(card, file, apdu.resp + 2, - apdu.resp[1]); - *file_out = file; - break; - case 0x00: /* proprietary coding */ - return SC_ERROR_UNKNOWN_DATA_RECEIVED; - default: - return SC_ERROR_UNKNOWN_DATA_RECEIVED; - } - return 0; + assert(iso_ops && iso_ops->select_file); + priv_data->file_id = 0; + return iso_ops->select_file(card, in_path, file_out); } static int _westcos2opensc_ac(u8 flag) @@ -616,7 +523,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file) sc_debug(card->ctx, "westcos_create_file\n"); memset(buf, 0, sizeof(buf)); - /* clef de transport */ + /* transport key */ r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL); if (r) return (r); @@ -638,7 +545,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file) case SC_FILE_TYPE_WORKING_EF: switch (file->ef_structure) { case SC_FILE_EF_TRANSPARENT: - buf[0] |= 0x20; /* pas de support transaction */ + buf[0] |= 0x20; /* no transaction support */ buf[1] |= 0; _convertion_ac_methode(file, HIGH, SC_AC_OP_READ, &buf[2], &buf[2 + 4]); @@ -652,7 +559,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file) buf[11] = (u8) ((file->size) % 256); break; case SC_FILE_EF_LINEAR_FIXED: - buf[0] |= 0x40; /* pas de support transaction */ + buf[0] |= 0x40; /* no transaction support */ buf[1] |= 0; _convertion_ac_methode(file, HIGH, SC_AC_OP_READ, &buf[2], &buf[2 + 4]); @@ -664,7 +571,7 @@ static int westcos_create_file(sc_card_t *card, struct sc_file *file) buf[11] = file->record_length; break; case SC_FILE_EF_CYCLIC: - buf[0] |= 0x60; /* pas de support transaction */ + buf[0] |= 0x60; /* no transaction support */ buf[1] |= 0; _convertion_ac_methode(file, HIGH, SC_AC_OP_READ, &buf[2], &buf[2 + 4]); @@ -765,7 +672,9 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, u8 * result, size_t * len) { int r; +#ifdef ENABLE_OPENSSL DES_key_schedule ks1, ks2; +#endif u8 buf[8]; if ((*len) < sizeof(buf)) return SC_ERROR_INVALID_ARGUMENTS; @@ -773,17 +682,21 @@ static int westcos_get_crypte_challenge(sc_card_t * card, const u8 * key, r = sc_get_challenge(card, buf, *len); if (r) return r; +#ifdef ENABLE_OPENSSL DES_set_key((const_DES_cblock *) & key[0], &ks1); DES_set_key((const_DES_cblock *) & key[8], &ks2); DES_ecb2_encrypt((const_DES_cblock *)buf, (DES_cblock*)result, &ks1, &ks2, DES_ENCRYPT); - return 0; + return SC_SUCCESS; +#else + return SC_ERROR_NOT_SUPPORTED; +#endif } static int westcos_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data, int *tries_left) { int r; - u8 buf[20]; //, result[20]; + u8 buf[20]; sc_apdu_t apdu; size_t len = 0; int pad = 0, use_pin_pad = 0, ins, p1 = 0; @@ -953,6 +866,7 @@ static int sc_lock_phase(sc_card_t * card, u8 phase) static int westcos_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) { + unsigned int i; int r; size_t buflen; u8 buf[256]; @@ -1088,9 +1002,9 @@ static int westcos_card_ctl(sc_card_t * card, unsigned long cmd, void *ptr) memcpy(temp, ck->key_template, sizeof(temp)); westcos_compute_aetb_crc(CRC_A, ck->new_key.key_value, ck->new_key.key_len, &temp[5], &temp[6]); - for (r = 0, temp[4] = 0xAA, lrc = 0; r < sizeof(temp); - r++) - lrc += temp[r]; + for (i = 0, temp[4] = 0xAA, lrc = 0; i < sizeof(temp); + i++) + lrc += temp[i]; temp[4] = (lrc % 256); buflen = sizeof(buf); r = westcos_get_crypte_challenge(card, @@ -1172,11 +1086,12 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, priv_data_t *priv_data = NULL; int pad; -#ifdef ENABLE_OPENSSL +#ifndef ENABLE_OPENSSL + r = SC_ERROR_NOT_SUPPORTED; +#else RSA *rsa = NULL; BIO *mem = BIO_new(BIO_s_mem()); -#endif if (card == NULL) return SC_ERROR_INVALID_ARGUMENTS; if (card->ctx->debug >= 1) @@ -1186,10 +1101,6 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, r = SC_ERROR_OUT_OF_MEMORY; goto out; } -#ifndef ENABLE_OPENSSL - r = SC_ERROR_NOT_SUPPORTED; - -#else if ((priv_data->env.flags) & SC_ALGORITHM_RSA_PAD_PKCS1) pad = RSA_PKCS1_PADDING; @@ -1220,13 +1131,13 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, BIO_set_mem_eof_return(mem, -1); if (!d2i_RSAPrivateKey_bio(mem, &rsa)) { if (card->ctx->debug >= 5) - sc_debug(card->ctx, "RSA clef invalide, %d\n", + sc_debug(card->ctx, "RSA key invalid, %d\n", ERR_get_error()); r = SC_ERROR_UNKNOWN; goto out; } - /* pkcs11 reroute routine cryptage vers la carte */ + /* pkcs11 reset openssl functions */ rsa->meth = RSA_PKCS1_SSLeay(); if (RSA_size(rsa) > outlen) { if (card->ctx->debug >= 5) @@ -1240,7 +1151,7 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, if (r == -1) { #ifdef DEBUG_SSL - print_openssl_erreur(); + print_openssl_error(); #endif if (card->ctx->debug >= 5) @@ -1251,13 +1162,13 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, } } - else { /* signature */ + else { /* sign */ r = RSA_private_encrypt(data_len, data, out, rsa, pad); if (r == -1) { #ifdef DEBUG_SSL - print_openssl_erreur(); + print_openssl_error(); #endif if (card->ctx->debug >= 5) @@ -1279,15 +1190,12 @@ static int westcos_sign_decipher(int mode, sc_card_t *card, r = outlen; #endif -#endif /* ENABLE_OPENSSL */ - out: -#ifdef ENABLE_OPENSSL +out: if (mem) BIO_free(mem); if (rsa) RSA_free(rsa); - -#endif +#endif /* ENABLE_OPENSSL */ if (keyfile) sc_file_free(keyfile); return r; diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 916728e8..5d6fe431 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -515,7 +515,7 @@ typedef struct { #define SC_RUTOKEN_DO_ALL_MIN_ID 0x1 /* MIN ID value of All DOs */ #define SC_RUTOKEN_DO_CHV_MAX_ID 0x1F /* MAX ID value of CHV-objects */ -#define SC_RUTOKEN_DO_NOCHV_MAX_ID 0xFE /* MAX ID value of All Other DOs */ +#define SC_RUTOKEN_DO_NOCHV_MAX_ID 0x7F /* MAX ID value of All Other DOs */ /* DO Default Lengths */ #define SC_RUTOKEN_DEF_LEN_DO_GOST 32 diff --git a/src/libopensc/muscle.c b/src/libopensc/muscle.c index c9a8bc04..abfb4a0e 100644 --- a/src/libopensc/muscle.c +++ b/src/libopensc/muscle.c @@ -427,10 +427,11 @@ void msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bu apdu->data = buffer; } -int msc_get_challenge(sc_card_t *card, short dataLength, short seedLength, u8 *seedData, u8* outputData) +int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short seedLength, u8 *seedData, u8 *outputData) { sc_apdu_t apdu; - int r, location, cse, len; + int r, location, cse; + size_t len; u8 *buffer, *ptr; location = (dataLength < MSC_MAX_READ) ? 1 : 2; /* 1 == APDU, 2 == (seed in 0xFFFFFFFE, out in 0xFFFFFFFF) */ diff --git a/src/libopensc/muscle.h b/src/libopensc/muscle.h index e39cd533..746124fb 100644 --- a/src/libopensc/muscle.h +++ b/src/libopensc/muscle.h @@ -54,7 +54,7 @@ void msc_unblock_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t b int msc_change_pin(sc_card_t *card, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength, int *tries); void msc_change_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, u8* buffer, size_t bufferLength, int pinNumber, const u8 *pinValue, int pinLength, const u8 *newPin, int newPinLength); -int msc_get_challenge(sc_card_t *card, short dataLength, short seedLength, u8 *seedData, u8* outputData); +int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short seedLength, u8 *seedData, u8 *outputData); int msc_generate_keypair(sc_card_t *card, int privateKey, int publicKey, int algorithm, int keySize, int options); int msc_extract_rsa_public_key(sc_card_t *card, diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 0aab3660..39898914 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -158,10 +158,6 @@ extern "C" { #define SC_ALGORITHM_MD5 128 #define SC_ALGORITHM_SHA1 129 #define SC_ALGORITHM_GOSTR3411 130 -/* FIXME: */ -/* -#define SC_ALGORITHM_GOSTHASH 130 -*/ /* Key derivation algorithms */ #define SC_ALGORITHM_PBKDF2 192 @@ -200,11 +196,6 @@ extern "C" { #define SC_ALGORITHM_GOSTR3410_HASH_GOSTR3411 0x00008000 #define SC_ALGORITHM_GOSTR3410_HASHES 0x00008000 -/* FIXME: */ -#define SC_ALGORITHM_GOST_CRYPT_PZ 0x0 -#define SC_ALGORITHM_GOST_CRYPT_GAMM 0x1 -#define SC_ALGORITHM_GOST_CRYPT_GAMMOS 0x2 - /* Event masks for sc_wait_for_event() */ #define SC_EVENT_CARD_INSERTED 0x0001 #define SC_EVENT_CARD_REMOVED 0x0002 diff --git a/src/libopensc/pkcs15-esinit.c b/src/libopensc/pkcs15-esinit.c index c7d7c342..b53c6402 100644 --- a/src/libopensc/pkcs15-esinit.c +++ b/src/libopensc/pkcs15-esinit.c @@ -41,10 +41,8 @@ static int entersafe_detect_card( sc_pkcs15_card_t *p15card) static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card) { - int r, i; + int r; char buf[256]; - sc_path_t path; - sc_file_t *file = NULL; sc_card_t *card = p15card->card; sc_serial_number_t serial; diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 5fc33e73..5d91cbc0 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -508,6 +508,10 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot) struct pcsc_private_data *priv = GET_PRIV_DATA(reader); struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot); int r; + u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE]; + size_t rcount; + DWORD i, feature_len, display_ioctl = 0; + PCSC_TLV_STRUCTURE *pcsc_tlv; r = refresh_slot_attributes(reader, slot); if (r) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index dd31be62..bcbcec2a 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -75,6 +75,7 @@ struct pkcs15_cert_object { #define cert_p15obj base.p15_object #define cert_pubkey base.related_pubkey #define cert_issuer base.related_cert +#define cert_prvkey base.related_privkey struct pkcs15_prkey_object { struct pkcs15_any_object base; @@ -84,7 +85,6 @@ struct pkcs15_prkey_object { #define prv_flags base.base.flags #define prv_p15obj base.p15_object #define prv_pubkey base.related_pubkey -#define prv_cert base.related_cert #define prv_next base.related_privkey struct pkcs15_pubkey_object { @@ -95,7 +95,7 @@ struct pkcs15_pubkey_object { }; #define pub_flags base.base.flags #define pub_p15obj base.p15_object -#define pub_cert base.related_cert +#define pub_genfrom base.related_cert #define __p15_type(obj) (((obj) && (obj)->p15_object)? ((obj)->p15_object->type) : (unsigned int)-1) #define is_privkey(obj) (__p15_type(obj) == SC_PKCS15_TYPE_PRKEY_RSA || __p15_type(obj) == SC_PKCS15_TYPE_PRKEY_GOSTR3410) @@ -350,7 +350,7 @@ __pkcs15_create_cert_object(struct pkcs15_fw_data *fw_data, } else obj2->pub_data = NULL; /* will copy from cert when cert is read */ - obj2->pub_cert = object; + obj2->pub_genfrom = object; object->cert_pubkey = obj2; if (cert_object != NULL) @@ -470,6 +470,9 @@ __pkcs15_prkey_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_prkey_ sc_pkcs15_id_t *id = &pk->prv_info->id; unsigned int i; + sc_debug(context, "Object is a private key and has id %s", + sc_pkcs15_print_id(id)); + for (i = 0; i < fw_data->num_objects; i++) { struct pkcs15_any_object *obj = fw_data->objects[i]; @@ -488,18 +491,12 @@ __pkcs15_prkey_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_prkey_ *pp = (struct pkcs15_prkey_object *) obj; } } else - if (is_cert(obj) && !pk->prv_cert) { - struct pkcs15_cert_object *cert; - - cert = (struct pkcs15_cert_object *) obj; - if (sc_pkcs15_compare_id(&cert->cert_info->id, id)) - pk->prv_cert = cert; - } else if (is_pubkey(obj) && !pk->prv_pubkey) { struct pkcs15_pubkey_object *pubkey; pubkey = (struct pkcs15_pubkey_object *) obj; if (sc_pkcs15_compare_id(&pubkey->pub_info->id, id)) { + sc_debug(context, "Associating object %d as public key", i); pk->prv_pubkey = pubkey; if (pk->prv_info->modulus_length == 0) pk->prv_info->modulus_length = pubkey->pub_info->modulus_length; @@ -511,25 +508,43 @@ __pkcs15_prkey_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_prkey_ static void __pkcs15_cert_bind_related(struct pkcs15_fw_data *fw_data, struct pkcs15_cert_object *cert) { - struct sc_pkcs15_cert *c1 = cert->cert_data, *c2; + struct sc_pkcs15_cert *c1 = cert->cert_data; + sc_pkcs15_id_t *id = &cert->cert_info->id; unsigned int i; - /* Loop over all certificates see if we find the certificate of - * the issuer */ + sc_debug(context, "Object is a certificate and has id %s", + sc_pkcs15_print_id(id)); + + /* Loop over all objects to see if we find the certificate of + * the issuer and the associated private key */ for (i = 0; i < fw_data->num_objects; i++) { struct pkcs15_any_object *obj = fw_data->objects[i]; - if (!is_cert(obj) || obj == (struct pkcs15_any_object *) cert) - continue; + if (is_cert(obj) && obj != (struct pkcs15_any_object *) cert) { + struct pkcs15_cert_object *cert2; + struct sc_pkcs15_cert *c2; - c2 = ((struct pkcs15_cert_object *) obj)->cert_data; + cert2 = (struct pkcs15_cert_object *) obj; + c2 = cert2->cert_data; - if (!c1 || !c2 || !c1->issuer_len || !c2->subject_len) - continue; - if (c1->issuer_len == c2->subject_len - && !memcmp(c1->issuer, c2->subject, c1->issuer_len)) { - cert->cert_issuer = (struct pkcs15_cert_object *) obj; - return; + if (!c1 || !c2 || !c1->issuer_len || !c2->subject_len) + continue; + if (c1->issuer_len == c2->subject_len + && !memcmp(c1->issuer, c2->subject, c1->issuer_len)) { + sc_debug(context, "Associating object %d (id %s) as issuer", + i, sc_pkcs15_print_id(&cert2->cert_info->id)); + cert->cert_issuer = (struct pkcs15_cert_object *) obj; + return; + } + } else + if (is_privkey(obj) && !cert->cert_prvkey) { + struct pkcs15_prkey_object *pk; + + pk = (struct pkcs15_prkey_object *) obj; + if (sc_pkcs15_compare_id(&pk->prv_info->id, id)) { + sc_debug(context, "Associating object %d as private key", i); + cert->cert_prvkey = pk; + } } } } @@ -547,6 +562,9 @@ pkcs15_bind_related_objects(struct pkcs15_fw_data *fw_data) if (obj->base.flags & SC_PKCS11_OBJECT_HIDDEN) continue; + + sc_debug(context, "Looking for objects related to object %d", i); + if (is_privkey(obj)) { __pkcs15_prkey_bind_related(fw_data, (struct pkcs15_prkey_object *) obj); } else if (is_cert(obj)) { @@ -578,7 +596,7 @@ check_cert_data_read(struct pkcs15_fw_data *fw_data, /* update the related public key object */ obj2 = cert->cert_pubkey; - obj2->pub_data = (sc_pkcs15_pubkey_t *)calloc(1, sizeof(sc_pkcs15_pubkey_t)); + obj2->pub_data = (sc_pkcs15_pubkey_t *)calloc(1, sizeof(sc_pkcs15_pubkey_t)); if (!obj2->pub_data) return SC_ERROR_OUT_OF_MEMORY; memcpy(obj2->pub_data, &cert->cert_data->key, sizeof(sc_pkcs15_pubkey_t)); @@ -613,6 +631,9 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, struct pkcs15_any_object *obj, CK_OBJECT_HANDLE_PTR pHandle) { + unsigned int i; + struct pkcs15_fw_data *card_fw_data; + if (obj == NULL || (obj->base.flags & (SC_PKCS11_OBJECT_HIDDEN | SC_PKCS11_OBJECT_RECURS))) return; @@ -632,14 +653,23 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot, switch (__p15_type(obj)) { case SC_PKCS15_TYPE_PRKEY_RSA: - if (obj->related_cert == NULL) - pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); - pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL); - break; case SC_PKCS15_TYPE_PRKEY_GOSTR3410: - if (obj->related_cert == NULL) - pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); - pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_cert, NULL); + pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); + card_fw_data = (struct pkcs15_fw_data *) slot->card->fw_data; + for (i = 0; i < card_fw_data->num_objects; i++) { + struct pkcs15_any_object *obj2 = card_fw_data->objects[i]; + struct pkcs15_cert_object *cert; + + if (!is_cert(obj2)) + continue; + + cert = (struct pkcs15_cert_object*) obj2; + + if ((struct pkcs15_any_object*)(cert->cert_prvkey) != obj) + continue; + + pkcs15_add_object(slot, obj2, NULL); + } break; case SC_PKCS15_TYPE_CERT_X509: pkcs15_add_object(slot, (struct pkcs15_any_object *) obj->related_pubkey, NULL); @@ -818,9 +848,14 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card) for (j=0; j < fw_data->num_objects; j++) { struct pkcs15_any_object *obj = fw_data->objects[j]; + /* "Fake" objects we've generated */ if (__p15_type(obj) == (unsigned int)-1) continue; - else if (!sc_pkcs15_compare_id(&pin_info->auth_id, &obj->p15_object->auth_id)) + /* Some objects have an auth_id even though they are + * not private. Just ignore those... */ + if (!(obj->p15_object->flags & SC_PKCS15_CO_FLAG_PRIVATE)) + continue; + if (!sc_pkcs15_compare_id(&pin_info->auth_id, &obj->p15_object->auth_id)) continue; if (is_privkey(obj)) { @@ -1020,7 +1055,7 @@ static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card, rc = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile); if (rc < 0) { - sc_lock(p11card->card); + sc_unlock(p11card->card); return sc_to_cryptoki_error(rc, p11card->reader); } @@ -1030,8 +1065,8 @@ static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card, args.pin_len = ulPinLen; rc = sc_pkcs15init_store_pin(fw_data->p15_card, profile, &args); - sc_lock(p11card->card); sc_pkcs15init_unbind(profile); + sc_unlock(p11card->card); if (rc < 0) return sc_to_cryptoki_error(rc, p11card->reader); @@ -1769,7 +1804,7 @@ static CK_RV pkcs15_set_attrib(struct sc_pkcs11_session *session, rc = sc_pkcs15init_bind(p11card->card, "pkcs15", NULL, &profile); if (rc < 0) { - rc = sc_unlock(p11card->card); + sc_unlock(p11card->card); return sc_to_cryptoki_error(rc, p11card->reader); } @@ -2000,25 +2035,43 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session, unsigned int usage; size_t len; - /* will use modulus from cert, or pubkey if possible */ - if (prkey->prv_cert && prkey->prv_cert->cert_pubkey) { - /* make sure we have read the cert to get modulus etc but only if needed. */ - switch(attr->type) { - case CKA_MODULUS: - case CKA_PUBLIC_EXPONENT: - case CKA_MODULUS_BITS: - if (check_cert_data_read(fw_data, prkey->prv_cert) != 0) { - /* no cert found, maybe we have a pub_key */ - if (prkey->prv_pubkey && prkey->prv_pubkey->pub_data) - key = prkey->prv_pubkey->pub_data; /* may be NULL */ - } else - key = prkey->prv_cert->cert_pubkey->pub_data; - break; - default: - key = prkey->prv_cert->cert_pubkey->pub_data; + /* PKCS#11 requires us to supply CKA_MODULUS for private keys, + * although that is not generally available from a smart card + * (the key is supposed to be safely locked away after all). + * + * To work around this, we hope that we either have an associated + * public key, or we try to find a certificate with the + * corresponding public key. + * + * Note: We do the same thing for CKA_PUBLIC_EXPONENT as some + * applications assume they can get that from the private + * key, something PKCS#11 doesn't guarantee. + */ + if ((attr->type == CKA_MODULUS) || (attr->type == CKA_PUBLIC_EXPONENT)) { + /* First see if we have a associated public key */ + if (prkey->prv_pubkey) + key = prkey->prv_pubkey->pub_data; + else { + /* Try to find a certificate with the public key */ + unsigned int i; + + for (i = 0; i < fw_data->num_objects; i++) { + struct pkcs15_any_object *obj = fw_data->objects[i]; + struct pkcs15_cert_object *cert; + + if (!is_cert(obj)) + continue; + + cert = (struct pkcs15_cert_object*) obj; + + if (cert->cert_prvkey != prkey) + continue; + + if (check_cert_data_read(fw_data, cert) == 0) + key = cert->cert_pubkey->pub_data; + } } - } else if (prkey->prv_pubkey) - key = prkey->prv_pubkey->pub_data; + } switch (attr->type) { case CKA_CLASS: @@ -2053,7 +2106,7 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session, break; case CKA_KEY_TYPE: check_attribute_buffer(attr, sizeof(CK_KEY_TYPE)); - if (key && key->algorithm == SC_ALGORITHM_GOSTR3410) + if (prkey->prv_p15obj->type == SC_PKCS15_TYPE_PRKEY_GOSTR3410) *(CK_KEY_TYPE*)attr->pValue = CKK_GOSTR3410; else *(CK_KEY_TYPE*)attr->pValue = CKK_RSA; @@ -2157,9 +2210,6 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj, case CKM_RSA_X_509: flags = SC_ALGORITHM_RSA_RAW; break; - case CKM_OPENSC_GOST: /* FIXME: */ - flags = SC_ALGORITHM_GOST; - break; case CKM_GOSTR3410: flags = SC_ALGORITHM_GOSTR3410_HASH_NONE; break; @@ -2235,10 +2285,8 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj, case CKM_RSA_X_509: flags |= SC_ALGORITHM_RSA_RAW; break; - case CKM_OPENSC_GOST: - flags |= SC_ALGORITHM_GOST; default: - return CKR_MECHANISM_INVALID; + return CKR_MECHANISM_INVALID; } rv = sc_lock(ses->slot->card->card); @@ -2336,7 +2384,7 @@ static CK_RV pkcs15_pubkey_get_attribute(struct sc_pkcs11_session *session, CK_ATTRIBUTE_PTR attr) { struct pkcs15_pubkey_object *pubkey = (struct pkcs15_pubkey_object*) object; - struct pkcs15_cert_object *cert = pubkey->pub_cert; + struct pkcs15_cert_object *cert = pubkey->pub_genfrom; struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fw_data; size_t len; @@ -2886,22 +2934,6 @@ static int register_mechanisms(struct sc_pkcs11_card *p11card) } if (alg_info->algorithm == SC_ALGORITHM_GOSTR3410) flags |= alg_info->flags; -#if 0 /* FIXME: */ - if (alg_info->algorithm == SC_ALGORITHM_GOST){ - mech_info.flags = CKF_HW | CKF_SIGN | CKF_ENCRYPT | CKF_DECRYPT; - #ifdef ENABLE_OPENSSL - mech_info.flags |= CKF_VERIFY; - #endif - mech_info.ulMinKeySize = 32; - mech_info.ulMaxKeySize = 32; - mt = sc_pkcs11_new_fw_mechanism(CKM_OPENSC_GOST, - &mech_info, CKK_RSA, NULL); - rc = sc_pkcs11_register_mechanism(p11card, mt); - sc_debug(card->ctx, "register GOST!!! %d", rc); - if(rc < 0) - return rc; - } -#endif alg_info++; } diff --git a/src/pkcs11/pkcs11-global.c b/src/pkcs11/pkcs11-global.c index 4e17fca8..8039bdaa 100644 --- a/src/pkcs11/pkcs11-global.c +++ b/src/pkcs11/pkcs11-global.c @@ -175,7 +175,8 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs) #if !defined(_WIN32) pid_t current_pid = getpid(); #endif - int i, rc, rv; + unsigned int i; + int rc, rv; sc_context_param_t ctx_opts; /* Handle fork() exception */ @@ -323,7 +324,7 @@ CK_RV C_GetSlotList(CK_BBOOL tokenPresent, /* only slots with token prese CK_ULONG_PTR pulCount) /* receives the number of slots */ { CK_SLOT_ID_PTR found = NULL; - int i; + unsigned int i; CK_ULONG numMatches; sc_pkcs11_slot_t *slot; CK_RV rv; diff --git a/src/pkcs11/pkcs11-opensc.h b/src/pkcs11/pkcs11-opensc.h index d6a00b45..6ab95303 100644 --- a/src/pkcs11/pkcs11-opensc.h +++ b/src/pkcs11/pkcs11-opensc.h @@ -3,8 +3,4 @@ /* OpenSC specific extensions */ -#define CKK_OPENSC_GOST (CKK_VENDOR_DEFINED+1) -#define CKA_OPENSC_GOST (CKA_VENDOR_DEFINED+1) -#define CKM_OPENSC_GOST (CKM_VENDOR_DEFINED+1) - #endif diff --git a/src/pkcs15init/keycache.c b/src/pkcs15init/keycache.c index 4c8eb135..017042eb 100644 --- a/src/pkcs15init/keycache.c +++ b/src/pkcs15init/keycache.c @@ -264,10 +264,6 @@ sc_keycache_set_pin_name(const sc_path_t *path, int ref, int name) s = new_entry(path, SC_AC_CHV, ref); if (s == NULL) return SC_ERROR_OUT_OF_MEMORY; - - s->len = sc_keycache_get_key(path, SC_AC_CHV, -1, s->value, MAX_SECRET); - if(s->len < 0) - return SC_ERROR_OBJECT_NOT_FOUND; } /* Set the pin name */ diff --git a/src/pkcs15init/pkcs15-cardos.c b/src/pkcs15init/pkcs15-cardos.c index 72b014de..c9fab1ee 100644 --- a/src/pkcs15init/pkcs15-cardos.c +++ b/src/pkcs15init/pkcs15-cardos.c @@ -253,7 +253,7 @@ cardos_store_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_prkey_t *key) { sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; - int algorithm, r; + int algorithm = 0, r; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { sc_debug(card->ctx, "CardOS supports RSA keys only."); @@ -306,7 +306,7 @@ cardos_generate_key(sc_profile_t *profile, sc_card_t *card, struct sc_cardctl_cardos_genkey_info args; struct sc_file *temp; u8 abignum[256]; - int algorithm, r, delete_it = 0, use_ext_rsa = 0; + int algorithm = 0, r, delete_it = 0, use_ext_rsa = 0; size_t keybits, rsa_max_size; int pin_id = -1; diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index 83f39ef1..b3417cde 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -232,10 +232,7 @@ static int myeid_generate_store_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_prkey_info_t *info) { struct sc_cardctl_myeid_gen_store_key_info args; - struct sc_cardctl_myeid_data_obj data_obj; - unsigned char raw_pubkey[256]; int r; - unsigned int mod_len; sc_file_t *prkf = NULL; /* Parameter check */ @@ -362,7 +359,7 @@ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card, data[17] = 0x00; data[18] = 0x00; - data[19] = 0x00; + data[19] = 0x00; /* FIXME, array is only 0..18 */ data_obj.Data = data; data_obj.DataLen = 0x10; diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index 321647d7..efcef804 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -32,53 +32,16 @@ #include "profile.h" #ifdef ENABLE_OPENSSL +#include #include #include #include - - #include #include #endif extern int sc_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2); -#if 0 -/* - * Get private and public key file - */ -static int _westcos_get_keyfiles(sc_profile_t *profile, sc_card_t *card, - const sc_path_t *df_path, - sc_file_t **prkf, sc_file_t **pukf) -{ - sc_path_t path = *df_path; - int r; - - /* Get the private key file */ - r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &path, prkf); - if (r < 0) { - char pbuf[SC_MAX_PATH_STRING_SIZE]; - - r = sc_path_print(pbuf, sizeof(pbuf), &path); - if (r != SC_SUCCESS) - pbuf[0] = '\0'; - - return r; - } - - /* Get the public key file */ - path.len -= 2; - sc_append_file_id(&path, 0x1012); - r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &path, pukf); - if (r < 0) { - sc_file_free(*prkf); - return r; - } - - return 0; -} -#endif /* currently unused */ - static int westcos_pkcs15init_init_card(sc_profile_t *profile, sc_card_t *card) { @@ -100,7 +63,6 @@ static int westcos_pkcs15init_create_dir(sc_profile_t *profile, /* Create the application DF */ r = sc_pkcs15init_create_file(profile, card, df); - //if(r) return r; r = sc_select_file(card, &df->path, NULL); if(r) return r; @@ -108,19 +70,6 @@ static int westcos_pkcs15init_create_dir(sc_profile_t *profile, return 0; } -#if 0 -/* -* Create a PIN domain (i.e. a sub-directory holding a user PIN) -*/ -static int westcos_pkcs15init_create_domain(sc_profile_t *profile, - sc_card_t *card, - const sc_pkcs15_id_t *id, - sc_file_t **ret) -{ - return SC_ERROR_NOT_SUPPORTED; //sc_pkcs15_create_pin_domain(profile, card, id, ret); -} -#endif /* currently unused */ - /* * Select the PIN reference */ @@ -151,7 +100,7 @@ static int westcos_pkcs15_create_pin(sc_profile_t *profile, sc_file_t *file = sc_file_new(); sc_path_t path; - if(pin_len>9 || puk_len>9 || pin_len<0 || puk_len<0) + if(pin_len>9 || puk_len>9) return SC_ERROR_INVALID_ARGUMENTS; file->type = SC_FILE_TYPE_INTERNAL_EF; @@ -179,8 +128,6 @@ static int westcos_pkcs15_create_pin(sc_profile_t *profile, if(r) return (r); } - //r = sc_pkcs15init_create_file(profile, card, file); - if(file) sc_file_free(file); @@ -308,24 +255,6 @@ static int westcos_pkcs15init_store_key(sc_profile_t *profile, sc_pkcs15_prkey_t *key) { return SC_ERROR_NOT_SUPPORTED; - -#if 0 - int r; - sc_file_t *keyfile; - sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; - - if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { - return SC_ERROR_NOT_SUPPORTED; - } - - r = SC_ERROR_NOT_SUPPORTED; //sc_profile_get_file_by_path(profile, &key_info->path, &keyfile); - if (r < 0) return r; - - //r = sc_pkcs15init_update_file(profile, card, keyfile, &key->der.data, &key->der.len); - - //sc_file_free(keyfile); - return r; -#endif } /* @@ -336,41 +265,56 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, sc_pkcs15_object_t *obj, sc_pkcs15_pubkey_t *pubkey) { - int r = SC_ERROR_UNKNOWN; +#ifndef ENABLE_OPENSSL + return SC_ERROR_NOT_SUPPORTED; +#else + int r = SC_ERROR_UNKNOWN; long lg; char *p; sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; -#ifdef ENABLE_OPENSSL - RSA *rsa = RSA_new(); - BIGNUM *bn = BN_new(); - BIO *mem = BIO_new(BIO_s_mem()); -#endif + RSA *rsa = NULL; + BIGNUM *bn = NULL; + BIO *mem = NULL; -#ifndef ENABLE_OPENSSL - r = SC_ERROR_NOT_SUPPORTED; -#else sc_file_t *prkf = NULL; if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) { return SC_ERROR_NOT_SUPPORTED; } - if(/*keyfile == NULL ||*/ rsa == NULL || bn == NULL || mem == NULL) +#if OPENSSL_VERSION_NUMBER>=0x00908000L + rsa = RSA_new(); + bn = BN_new(); + mem = BIO_new(BIO_s_mem()); + + if(rsa == NULL || bn == NULL || mem == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto out; } /* pkcs11 re-route routine cryptage vers la carte fixe default to use openssl */ - rsa->meth = RSA_PKCS1_SSLeay(); - if(!BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(rsa, key_info->modulus_length, bn, NULL)) +#else + mem = BIO_new(BIO_s_mem()); + + if(mem == NULL) + { + r = SC_ERROR_OUT_OF_MEMORY; + goto out; + } + + rsa = RSA_generate_key(key_info->modulus_length, RSA_F4, NULL, NULL); + if (!rsa) +#endif { r = SC_ERROR_UNKNOWN; goto out; } + rsa->meth = RSA_PKCS1_SSLeay(); + if(pubkey != NULL) { if(!i2d_RSAPublicKey_bio(mem, rsa)) @@ -386,7 +330,7 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, r = sc_pkcs15_decode_pubkey(card->ctx, pubkey, p, lg); } - BIO_reset(mem); + (void) BIO_reset(mem); if(!i2d_RSAPrivateKey_bio(mem, rsa)) { @@ -421,9 +365,9 @@ out: RSA_free(rsa); if(prkf) sc_file_free(prkf); -#endif return r; +#endif } static int westcos_pkcs15init_finalize_card(sc_card_t *card) diff --git a/src/pkcs15init/rutoken.profile b/src/pkcs15init/rutoken.profile index ec8c7a36..9e32d99f 100644 --- a/src/pkcs15init/rutoken.profile +++ b/src/pkcs15init/rutoken.profile @@ -28,7 +28,7 @@ pkcs15 { # Default settings. # This option block will always be processed. -option default_32k { +option default { macros { ti-size = 128; odf-size = 128; @@ -43,8 +43,7 @@ option default_32k { # This option is for cards with very little memory. # It sets the size of various PKCS15 directory files # to 128 or 256, respectively. -#option small { -option default { +option small { macros { ti-size = 64; odf-size = 128; diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 309ae191..8d78e287 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -1563,7 +1563,7 @@ static int do_asn1(int argc, char **argv) goto err; } if ((size_t)r != len) { - printf("expecting %d, got only %d bytes.\n", len, r); + printf("expecting %ld, got only %d bytes.\n", len, r); goto err; } diff --git a/src/tools/pkcs11-tool.c b/src/tools/pkcs11-tool.c index 14a00f70..36e95fdf 100644 --- a/src/tools/pkcs11-tool.c +++ b/src/tools/pkcs11-tool.c @@ -3579,7 +3579,6 @@ static struct mech_info p11_mechanisms[] = { { CKM_DSA_PARAMETER_GEN, "DSA-PARAMETER-GEN", NULL }, { CKM_DH_PKCS_PARAMETER_GEN,"DH-PKCS-PARAMETER-GEN", NULL }, { CKM_X9_42_DH_PARAMETER_GEN,"X9-42-DH-PARAMETER-GEN", NULL }, - { CKM_OPENSC_GOST, "GOST", NULL }, { NO_MECHANISM, NULL, NULL } }; diff --git a/src/tools/util.c b/src/tools/util.c index 9870f511..233a13d2 100644 --- a/src/tools/util.c +++ b/src/tools/util.c @@ -51,7 +51,7 @@ int util_connect_card(sc_context_t *ctx, sc_card_t **cardp, return 1; } if (reader_id < 0) { - int i; + unsigned int i; /* Automatically try to skip to a reader with a card if reader not specified */ for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) { reader = sc_ctx_get_reader(ctx, i); diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 9b1852ca..cf4775c0 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -358,15 +359,9 @@ int main(int argc, char *argv[]) sc_context_t *ctx = NULL; sc_file_t *file = NULL; sc_path_t path; - RSA *rsa = RSA_new(); - BIGNUM *bn = BN_new(); - BIO *mem = BIO_new(BIO_s_mem()); - - if(rsa == NULL || bn == NULL || mem == NULL) - { - fprintf(stderr,"Not enougth memory.\n"); - goto out; - } + RSA *rsa = NULL; + BIGNUM *bn = NULL; + BIO *mem = NULL; while(i=0x00908000L + rsa = RSA_new(); + bn = BN_new(); + mem = BIO_new(BIO_s_mem()); + + if(rsa == NULL || bn == NULL || mem == NULL) + { + fprintf(stderr,"Not enougth memory.\n"); + goto out; + } + if(!BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(rsa, keylen, bn, NULL)) +#else + rsa = RSA_generate_key(keylen, RSA_F4, NULL, NULL); + mem = BIO_new(BIO_s_mem()); + + if(mem == NULL) + { + fprintf(stderr,"Not enougth memory.\n"); + goto out; + } + + if (!rsa) +#endif { fprintf(stderr, "RSA_generate_key_ex return %d\n", ERR_get_error()); From 30ab50600b003461eff0c90dbb342bc86d82dcce Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 25 Oct 2009 20:22:11 +0000 Subject: [PATCH 36/57] Merged [3783:3794/trunk] git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3795 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-myeid.c | 199 +++++++++++++++++++++--------- src/libopensc/card-westcos.c | 116 ++++++++---------- src/libopensc/cardctl.h | 4 +- src/libopensc/p15emu-westcos.c | 2 +- src/pkcs11/openssl.c | 12 +- src/pkcs15init/myeid.profile | 171 +++++++++++++++++++++++--- src/pkcs15init/pkcs15-myeid.c | 210 ++++++++++++++++++++++---------- src/pkcs15init/pkcs15-westcos.c | 6 +- src/tools/westcos-tool.c | 57 ++++----- 9 files changed, 534 insertions(+), 243 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index c622d479..0238af4d 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -25,23 +25,19 @@ #include #include - -static enum LOAD_KEY { - LOAD_KEY_MODULUS = 0x80, - LOAD_KEY_PUBLIC_EXPONENT = 0x81, - LOAD_KEY_PRIME_P = 0x83, - LOAD_KEY_PRIME_Q = 0x84, - LOAD_KEY_DP1 = 0x85, - LOAD_KEY_DQ1 = 0x86, - LOAD_KEY_INVQ = 0x87 -}; +#define LOAD_KEY_MODULUS 0x80 +#define LOAD_KEY_PUBLIC_EXPONENT 0x81 +#define LOAD_KEY_PRIME_P 0x83 +#define LOAD_KEY_PRIME_Q 0x84 +#define LOAD_KEY_DP1 0x85 +#define LOAD_KEY_DQ1 0x86 +#define LOAD_KEY_INVQ 0x87 static struct sc_card_operations myeid_ops; static struct sc_card_driver myeid_drv = { "MyEID cards with PKCS#15 applet", "myeid", - &myeid_ops, - NULL, 0, NULL + &myeid_ops }; static const char *myeid_atrs[] = { @@ -93,6 +89,7 @@ static int myeid_init(struct sc_card *card) /* State that we have an RNG */ card->caps |= SC_CARD_CAP_RNG; + SC_FUNC_CALLED(card->ctx, 1); return 0; } @@ -107,9 +104,9 @@ static int acl_to_byte(const struct sc_acl_entry *e) case SC_AC_TERM: case SC_AC_AUT: if (e->key_ref == SC_AC_KEY_REF_NONE) - return -1; + return 0x00; if (e->key_ref < 1 || e->key_ref > 14) - return -1; + return 0x00; return e->key_ref; case SC_AC_NEVER: return 0x0F; @@ -182,28 +179,28 @@ static int myeid_select_file(struct sc_card *card, const struct sc_path *in_path struct sc_file **file) { int r; - + SC_FUNC_CALLED(card->ctx, 1); r = iso_ops->select_file(card, in_path, file); - if (r) - return r; - if (file != NULL) { + if (r == 0 && file != NULL) { parse_sec_attr(*file, (*file)->sec_attr, (*file)->sec_attr_len); } - - return 0; + SC_FUNC_RETURN(card->ctx, 1, r); } static int myeid_read_binary(struct sc_card *card, unsigned int idx, u8 * buf, size_t count, unsigned long flags) { - return iso_ops->read_binary(card, idx, buf, count, flags); + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, iso_ops->read_binary(card, idx, buf, count, flags)); } static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen) { struct sc_apdu apdu; - int r; + int r,i; + + SC_FUNC_CALLED(card->ctx, 1); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0x01, 0xA1); apdu.resp = buf; @@ -225,9 +222,10 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file, const u8 *tag = NULL; int r ; + SC_FUNC_CALLED(card->ctx, 1); r = iso_ops->process_fci(card, file, buf, buflen); if (r < 0) - return r; + SC_FUNC_RETURN(card->ctx, 1, r); if(file->type == SC_FILE_EF_UNKNOWN) { @@ -237,16 +235,23 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file, file->type = SC_FILE_TYPE_INTERNAL_EF; } } + if(file->sec_attr_len >= 3) + { + sc_debug(card->ctx, "id (%X) sec_attr (%X %X %X) \n", file->id, + file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]); + } - return 0; + SC_FUNC_RETURN(card->ctx, 1, 0); } static int encode_file_structure(sc_card_t *card, const sc_file_t *file, u8 *out, size_t *outlen) { + const sc_acl_entry_t *read, *update, *delete; u8 buf[40]; int i; + SC_FUNC_CALLED(card->ctx, 1); /* PrivateKey * 0E0000019 6217 81020400 820111 83024B01 8603000000 85028000 8A0100 RESULT 6984 * 6217 81020400 820111 83024B01 8603000000 85021000 8A0100 */ @@ -283,6 +288,41 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, buf[15] = file->sec_attr[0]; buf[16] = file->sec_attr[1]; buf[17] = file->sec_attr[2]; + + sc_debug(card->ctx, "id (%X), sec_attr %X %X %X\n", file->id, + file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]); + } + else + { + delete = sc_file_get_acl_entry(file, SC_AC_OP_DELETE); + + switch (file->type) { + case SC_FILE_TYPE_WORKING_EF: + + read = sc_file_get_acl_entry(file, SC_AC_OP_READ); + update = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE); + + buf[15] = (acl_to_byte(read) << 4) | acl_to_byte(update); + buf[16] = (acl_to_byte(delete)<< 4) | 0x0F; + break; + case SC_FILE_TYPE_INTERNAL_EF: + + read = sc_file_get_acl_entry(file, SC_AC_OP_CRYPTO); + update = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE); + + buf[15] = (acl_to_byte(read) << 4) | acl_to_byte(update); + buf[16] = (acl_to_byte(delete)<< 4) | 0x0F; + break; + case SC_FILE_TYPE_DF: + + update = sc_file_get_acl_entry(file, SC_AC_OP_CREATE); + + buf[15] = (acl_to_byte(update) << 4) | acl_to_byte(update); + buf[16] = (acl_to_byte(delete) << 4) | 0x0F; + break; + default: + break; + } } /* Proprietary Information */ @@ -312,10 +352,10 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, { buf[25] = 0x84; buf[26] = (u8)file->namelen; + for(i=0;i < (int)file->namelen;i++) - { buf[i + 26] = file->name[i]; - } + buf[1] = 0x19 + file->namelen + 2; } break; @@ -327,7 +367,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, *outlen = buf[1]+2; memcpy(out, buf, *outlen); - return 0; + SC_FUNC_RETURN(card->ctx, 1, 0); } static int myeid_create_file(struct sc_card *card, struct sc_file *file) @@ -337,9 +377,12 @@ static int myeid_create_file(struct sc_card *card, struct sc_file *file) size_t buflen; int r; + SC_FUNC_CALLED(card->ctx, 1); + r = encode_file_structure(card, file, sbuf, &buflen); if (r) - return r; + SC_FUNC_RETURN(card->ctx, 1, r); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE0, 0x00, 0x00); apdu.data = sbuf; apdu.datalen = buflen; @@ -348,44 +391,48 @@ static int myeid_create_file(struct sc_card *card, struct sc_file *file) r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x6A && apdu.sw2 == 0x89) - return SC_ERROR_FILE_ALREADY_EXISTS; + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_FILE_ALREADY_EXISTS); + r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, r, "Card returned error"); - - return 0; } /* no record oriented file services */ static int myeid_read_record_unsupp(struct sc_card *card, unsigned int rec_nr, u8 *buf, size_t count, unsigned long flags) { - return SC_ERROR_NOT_SUPPORTED; + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } static int myeid_wrupd_record_unsupp(struct sc_card *card, unsigned int rec_nr, const u8 *buf, size_t count, unsigned long flags) { - return SC_ERROR_NOT_SUPPORTED; + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } static int myeid_append_record_unsupp(struct sc_card *card, const u8 *buf, size_t count, unsigned long flags) { - return SC_ERROR_NOT_SUPPORTED; + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } static int myeid_write_binary(struct sc_card *card, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) { - return iso_ops->write_binary(card, idx, buf, count, flags); + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, iso_ops->write_binary(card, idx, buf, count, flags)); } static int myeid_update_binary(struct sc_card *card, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) { - return iso_ops->update_binary(card, idx, buf, count, flags); + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, iso_ops->update_binary(card, idx, buf, count, flags)); } static int myeid_delete_file(struct sc_card *card, const struct sc_path *path) @@ -408,9 +455,33 @@ static int myeid_delete_file(struct sc_card *card, const struct sc_path *path) r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); - return sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_FUNC_RETURN(card->ctx, 1, sc_check_sw(card, apdu.sw1, apdu.sw2)); } +static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, + int *tries_left) +{ + + SC_FUNC_CALLED(card->ctx, 1); + sc_debug(card->ctx, "ref (%d), pin1 len(%d), pin2 len (%d)\n", + data->pin_reference, data->pin1.len, data->pin2.len); + + if(data->pin1.len > 8 || data->pin2.len > 8) + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_PIN_LENGTH); + + data->flags |= SC_PIN_CMD_NEED_PADDING; + if(data->cmd == SC_PIN_CMD_VERIFY) + { + u8 buf[8]; + memset(buf, 0xFF, sizeof(buf)); + memcpy(&buf[0], (u8 *)data->pin1.data, data->pin1.len); /* copy pin*/ + data->pin1.data = buf; + data->pin1.len = 8; + + } + + SC_FUNC_RETURN(card->ctx, 1, iso_ops->pin_cmd(card, data, tries_left)); +} static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env, int se_num) @@ -421,7 +492,7 @@ static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env int r, locked = 0; assert(card != NULL && env != NULL); - + SC_FUNC_CALLED(card->ctx, 1); if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) { @@ -504,12 +575,14 @@ static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env err: if (locked) sc_unlock(card); - return r; + SC_FUNC_RETURN(card->ctx, 1, r); } static int myeid_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) { + SC_FUNC_CALLED(card->ctx, 1); + if (env->flags & SC_SEC_ENV_ALG_PRESENT) { sc_security_env_t tmp; @@ -543,6 +616,8 @@ static int myeid_compute_signature(struct sc_card *card, const u8 * data, u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + SC_FUNC_CALLED(card->ctx, 1); + assert(card != NULL && data != NULL && out != NULL); if (datalen > 256) SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS); @@ -591,6 +666,8 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + SC_FUNC_CALLED(card->ctx, 1); + assert(card != NULL && crgram != NULL && out != NULL); SC_FUNC_CALLED(card->ctx, 2); if (crgram_len > 256) @@ -733,6 +810,7 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; int r, len; + SC_FUNC_CALLED(card->ctx, 1); len = 0; if(value_len == 0 || value == NULL) return 0; @@ -795,7 +873,6 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_FUNC_RETURN(card->ctx, 1, r); - } /* Generate or store a key */ @@ -804,8 +881,9 @@ static int myeid_generate_store_key(struct sc_card *card, { struct sc_apdu apdu; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - int r,len; + int r=0,len; + SC_FUNC_CALLED(card->ctx, 1); /* Setup key-generation paramters */ if (data->op_type == OP_TYPE_GENERATE) { @@ -831,8 +909,6 @@ static int myeid_generate_store_key(struct sc_card *card, r = sc_check_sw(card, apdu.sw1, apdu.sw2); SC_TEST_RET(card->ctx, r, "GENERATE_KEY returned error"); - - SC_FUNC_RETURN(card->ctx, 1, r); } else { @@ -850,10 +926,10 @@ static int myeid_generate_store_key(struct sc_card *card, data->mod, data->mod_len)) >= 0 && (r=myeid_loadkey(card, LOAD_KEY_PUBLIC_EXPONENT, data->pubexp, data->pubexp_len)) >= 0) - return r; + SC_FUNC_RETURN(card->ctx, 1, r); } - return r; + SC_FUNC_RETURN(card->ctx, 1, r); } static int myeid_activate_card(struct sc_card *card) @@ -862,6 +938,7 @@ static int myeid_activate_card(struct sc_card *card) u8 sbuf[] ="\xA0\x00\x00\x00\x63\x50\x4B\x43\x53\x2D\x31\x35"; sc_apdu_t apdu; + SC_FUNC_CALLED(card->ctx, 1); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x44, 0x04, 0x00); apdu.cla = 0x00; apdu.data = sbuf; @@ -883,6 +960,7 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) sc_apdu_t apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + SC_FUNC_CALLED(card->ctx, 1); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0xA0); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -907,28 +985,38 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) /* copy and return serial number */ memcpy(serial, &card->serialnr, sizeof(*serial)); - return SC_SUCCESS; + SC_FUNC_RETURN(card->ctx, 1, r); } static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) { + int r = SC_ERROR_NOT_SUPPORTED; + SC_FUNC_CALLED(card->ctx, 1); + switch(cmd) { case SC_CARDCTL_MYEID_PUTDATA: - return myeid_putdata(card, + r = myeid_putdata(card, (struct sc_cardctl_myeid_data_obj*) ptr); + break; case SC_CARDCTL_MYEID_GETDATA: - return myeid_getdata(card, + r = myeid_getdata(card, (struct sc_cardctl_myeid_data_obj*) ptr); + break; case SC_CARDCTL_MYEID_GENERATE_KEY: - return myeid_generate_store_key(card, + r = myeid_generate_store_key(card, (struct sc_cardctl_myeid_gen_store_key_info *) ptr); + break; case SC_CARDCTL_MYEID_ACTIVATE_CARD: - return myeid_activate_card(card); + r = myeid_activate_card(card); + break; case SC_CARDCTL_GET_SERIALNR: - return myeid_get_serialnr(card, (sc_serial_number_t *)ptr); + r = myeid_get_serialnr(card, (sc_serial_number_t *)ptr); + break; + case SC_CARDCTL_LIFECYCLE_SET: + case SC_CARDCTL_LIFECYCLE_GET: + break; } - - return SC_ERROR_NOT_SUPPORTED; + SC_FUNC_RETURN(card->ctx, 1, r); } /* "The PINs are "global" in a PKCS#15 sense, meaning that they remain valid @@ -938,7 +1026,8 @@ static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) */ static int myeid_logout(struct sc_card *card) { - return 0; /* Can't */ + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, 0); } static struct sc_card_driver * sc_get_driver(void) @@ -968,7 +1057,7 @@ static struct sc_card_driver * sc_get_driver(void) myeid_ops.logout = myeid_logout; myeid_ops.process_fci = myeid_process_fci; myeid_ops.card_ctl = myeid_card_ctl; - + myeid_ops.pin_cmd = myeid_pin_cmd; return &myeid_drv; } diff --git a/src/libopensc/card-westcos.c b/src/libopensc/card-westcos.c index 6608f1cd..e9a780e2 100644 --- a/src/libopensc/card-westcos.c +++ b/src/libopensc/card-westcos.c @@ -144,19 +144,12 @@ static int westcos_check_sw(sc_card_t * card, unsigned int sw1, return iso_ops->check_sw(card, sw1, sw2); } -typedef struct mon_atr { - size_t len; - int flags; - u8 *atr, *mask; -} mon_atr_t; - -static mon_atr_t atrs[] = { - {13, 0x00, - "\x3f\x69\x00\x00\x00\x64\x01\x00\x00\x00\x80\x90\x00", - "\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\xf0\xff\xff"}, - {12, JAVACARD, - "\x3b\x95\x94\x80\x1F\xC3\x80\x73\xC8\x21\x13\x54", - "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"} +static struct sc_atr_table westcos_atrs[] = { + /* westcos 2ko */ + { "3F:69:00:00:00:64:01:00:00:00:80:90:00", "ff:ff:ff:ff:ff:ff:ff:00:00:00:f0:ff:ff", NULL, 0x00, 0, NULL }, + /* westcos applet */ + { "3B:95:94:80:1F:C3:80:73:C8:21:13:54", "ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff", NULL, JAVACARD, 0, NULL }, + { NULL, NULL, NULL, 0, 0, NULL } }; static int westcos_finish(sc_card_t * card) @@ -172,59 +165,35 @@ static int westcos_finish(sc_card_t * card) static int westcos_match_card(sc_card_t * card) { - u8 *p, j; - size_t i; - mon_atr_t *matr; - if (card->ctx->debug >= 1) - sc_debug(card->ctx, "westcos_match_card %d, %X:%X:%X\n", - card->atr_len, card->atr[0], card->atr[1], - card->atr[2]); - for (i = 0; i < sizeof(atrs) / sizeof(*atrs); i++) { - matr = &atrs[i]; - if (matr->len != card->atr_len) - continue; - p = card->atr; - for (j = 0; j < card->atr_len; j++) { - if (((matr->mask[j]) & (*p)) != (matr->atr[j])) - break; - p++; - if (*p == ':') - p++; - } - if (j >= card->atr_len) { - if (matr->flags & JAVACARD) { - int r; - sc_apdu_t apdu; - u8 aid[] = { - 0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01 - }; - sc_format_apdu(card, &apdu, - SC_APDU_CASE_3_SHORT, 0xA4, 0x04, - 0); - apdu.cla = 0x00; - apdu.lc = sizeof(aid); - apdu.datalen = sizeof(aid); - apdu.data = aid; - r = sc_transmit_apdu(card, &apdu); - if (r) - continue; - r = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (r) - continue; - } - card->drv_data = malloc(sizeof(priv_data_t)); - if (card->drv_data == NULL) - return SC_ERROR_OUT_OF_MEMORY; - memset(card->drv_data, 0, sizeof(card->drv_data)); - if (matr->flags & JAVACARD) { - priv_data_t *priv_data = - (priv_data_t *) card->drv_data; - priv_data->flags |= JAVACARD; - } - return 1; - } + int i; + + i = _sc_match_atr(card, westcos_atrs, &card->type); + if (i < 0) + return 0; + + /* JAVACARD, look for westcos applet */ + if (i == 1) { + int r; + sc_apdu_t apdu; + u8 aid[] = { + 0xA0, 0x00, 0xCE, 0x00, 0x07, 0x01 + }; + sc_format_apdu(card, &apdu, + SC_APDU_CASE_3_SHORT, 0xA4, 0x04, + 0); + apdu.cla = 0x00; + apdu.lc = sizeof(aid); + apdu.datalen = sizeof(aid); + apdu.data = aid; + r = sc_transmit_apdu(card, &apdu); + if (r) + return 0; + r = sc_check_sw(card, apdu.sw1, apdu.sw2); + if (r) + return 0; } - return 0; + + return 1; } static int westcos_init(sc_card_t * card) @@ -232,8 +201,19 @@ static int westcos_init(sc_card_t * card) int r; const char *default_key; unsigned long exponent, flags; - if (card == NULL || card->drv_data == NULL) + if (card == NULL)// || card->drv_data == NULL) return SC_ERROR_INVALID_ARGUMENTS; + + card->drv_data = malloc(sizeof(priv_data_t)); + if (card->drv_data == NULL) + return SC_ERROR_OUT_OF_MEMORY; + memset(card->drv_data, 0, sizeof(card->drv_data)); + if (card->type & JAVACARD) { + priv_data_t *priv_data = + (priv_data_t *) card->drv_data; + priv_data->flags |= JAVACARD; + } + card->cla = 0x00; card->max_send_size = 240; card->max_recv_size = 240; @@ -260,9 +240,9 @@ static int westcos_init(sc_card_t * card) priv_data_t *priv_data = (priv_data_t *) (card->drv_data); priv_data->default_key.key_reference = 0; priv_data->default_key.key_len = - sizeof(priv_data->default_key.key_value); + sizeof(priv_data->default_key.key_value); r = sc_hex_to_bin(default_key, priv_data->default_key.key_value, - &(priv_data->default_key.key_len)); + &(priv_data->default_key.key_len)); if (r) return (r); } diff --git a/src/libopensc/cardctl.h b/src/libopensc/cardctl.h index 5d6fe431..29d75fa5 100644 --- a/src/libopensc/cardctl.h +++ b/src/libopensc/cardctl.h @@ -488,8 +488,8 @@ typedef struct sc_cardctl_asepcos_activate_file { typedef struct { int key_reference; - int key_len; //8, 16 or 24 - u8 key_value[24]; + size_t key_len; //8, 16 or 24 + u8 key_value[24]; }sc_autkey_t; typedef struct { diff --git a/src/libopensc/p15emu-westcos.c b/src/libopensc/p15emu-westcos.c index 77e0d1bb..d66e5023 100644 --- a/src/libopensc/p15emu-westcos.c +++ b/src/libopensc/p15emu-westcos.c @@ -32,7 +32,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) { int i, r; int modulus_length = 0, usage = 0; - u8 buf[256]; + char buf[256]; sc_card_t *card = p15card->card; sc_context_t *ctx = card->ctx; sc_serial_number_t serial; diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index e84e9b3e..786329d6 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -14,8 +14,11 @@ #include #include #if OPENSSL_VERSION_NUMBER >= 0x10000000L -#include #include +#include /* for OPENSSL_NO_EC */ +#ifndef OPENSSL_NO_EC +#include +#endif /* OPENSSL_NO_EC */ #endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */ static CK_RV sc_pkcs11_openssl_md_init(sc_pkcs11_operation_t *); @@ -248,7 +251,7 @@ sc_pkcs11_gen_keypair_soft(CK_KEY_TYPE keytype, CK_ULONG keybits, return CKR_OK; } -#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) static void reverse(unsigned char *buf, size_t len) { @@ -328,7 +331,7 @@ static CK_RV gostr3410_verify_data(const unsigned char *pubkey, int pubkey_len, return CKR_GENERAL_ERROR; return ret_vrf == 1 ? CKR_OK : CKR_SIGNATURE_INVALID; } -#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */ +#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */ /* If no hash function was used, finish with RSA_public_decrypt(). * If a hash function was used, we can make a big shortcut by @@ -346,11 +349,12 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, if (mech == CKM_GOSTR3410) { -#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) return gostr3410_verify_data(pubkey, pubkey_len, pubkey_params, pubkey_params_len, data, data_len, signat, signat_len); #else + (void)pubkey_params, (void)pubkey_params_len; /* no warning */ return CKR_FUNCTION_NOT_SUPPORTED; #endif } diff --git a/src/pkcs15init/myeid.profile b/src/pkcs15init/myeid.profile index 063553d5..76962559 100644 --- a/src/pkcs15init/myeid.profile +++ b/src/pkcs15init/myeid.profile @@ -1,20 +1,77 @@ # # PKCS15 r/w profile for MyEID cards # + cardinfo { + label = "MyEID"; + manufacturer = "Aventra Ltd."; + min-pin-length = 4; max-pin-length = 8; pin-encoding = ascii-numeric; - pin-pad-char = 0x00; + pin-pad-char = 0xFF; +} + +# +# The following controls some aspects of the PKCS15 we put onto +# the card. +# +pkcs15 { + # Put certificates into the CDF itself? + direct-certificates = no; + # Put the DF length into the ODF file? + encode-df-length = no; + # Have a lastUpdate field in the EF(TokenInfo)? + do-last-update = no; +} + +option default { + macros { + #protected = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + #unprotected = READ=NONE, UPDATE=CHV1, DELETE=CHV1; + + unusedspace-size = 512; + odf-size = 256; + aodf-size = 384; + cdf-size = 512; + prkdf-size = 1485; + pukdf-size = 1200; + dodf-size = 256; + } } # Define reasonable limits for PINs and PUK # Note that we do not set a file path or reference # here; that is done dynamically. PIN user-pin { + reference = 1; + auth-id = 1; + min-length = 4; + max-length = 8; attempts = 3; + flags = initialized, needs-padding; } + PIN user-puk { + min-length = 4; + max-length = 8; attempts = 10; + flags = needs-padding; +} + +PIN so-pin { + reference = 2; + auth-id = 2; + min-length = 4; + max-length = 8; + attempts = 4; + flags = initialized, soPin, needs-padding; +} + +PIN so-puk { + min-length = 4; + max-length = 8; + attempts = 9; + flags = needs-padding; } # Additional filesystem info. @@ -22,32 +79,114 @@ PIN user-puk { # main profile. filesystem { DF MF { + path = 3F00; + type = DF; + acl = DELETE=CHV2; #Erase PIN + + # This is the DIR file + EF DIR { + file-id = 2F00; + structure = transparent; + size = 128; + acl = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } DF PKCS15-AppDF { + type = DF; + file-id = 5015; + acl = DELETE=NONE, CREATE=CHV1; + + EF PKCS15-ODF { + file-id = 5031; + structure = transparent; + size = $odf-size; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + EF PKCS15-TokenInfo { + file-id = 5032; + structure = transparent; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + EF PKCS15-UnusedSpace { + file-id = 5033; + structure = transparent; + size = $unusedspace-size; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + EF PKCS15-AODF { + file-id = 4401; + structure = transparent; + size = $aodf-size; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + EF PKCS15-PrKDF { + file-id = 4402; + structure = transparent; + size = $prkdf-size; + acl = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + EF PKCS15-PuKDF { + file-id = 4403; + structure = transparent; + size = $pukdf-size; + acl = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + EF PKCS15-CDF { + file-id = 4404; + structure = transparent; + size = $cdf-size; + acl = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + EF PKCS15-DODF { + file-id = 4405; + structure = transparent; + size = $dodf-size; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } EF template-private-key { type = internal-ef; - file-id = 4B01; # This is the base FileID - size = 266; # 266 is enough for 1024-bit keys - ACL = *=NEVER, CRYPTO=$PIN, UPDATE=$PIN; + file-id = 4B01; + size = 1024; + ACL = CRYPTO=CHV1, UPDATE=CHV1, DELETE=CHV2; } EF template-public-key { + structure = transparent; file-id = 5501; - ACL = *=NEVER, READ=NONE, UPDATE=$PIN; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; } EF template-certificate { file-id = 4301; - ACL = *=NEVER, READ=NONE, UPDATE=$PIN; + structure = transparent; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + template key-domain { + # This is a dummy entry - pkcs15-init insists that + # this is present + EF private-key { + file-id = 4B00; + type = internal-ef; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + EF public-key { + file-id = 4300; + structure = transparent; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; + } + + # Certificate template + EF certificate { + file-id = 5300; + structure = transparent; + ACL = READ=NONE, UPDATE=CHV1, DELETE=CHV2; } - EF template-extractable-key { - file-id = 7000; - ACL = *=NEVER, READ=$PIN, UPDATE=$PIN; } } } } - -# Define an SO pin -# This PIN is not used yet. -#PIN sopin { -# file = sopinfile; -# reference = 0; -#} diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index b3417cde..cece5444 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -21,6 +21,7 @@ #ifdef HAVE_CONFIG_H #include #endif +#include #include #include #include @@ -31,7 +32,7 @@ #include "keycache.h" #include "profile.h" -#define MYEID_MAX_PINS 5 +#define MYEID_MAX_PINS 14 unsigned char MYEID_DEFAULT_PUBKEY[] = {0x01, 0x00, 0x01}; #define MYEID_DEFAULT_PUBKEY_LEN sizeof(MYEID_DEFAULT_PUBKEY) @@ -44,7 +45,26 @@ static int myeid_create_pin_internal(sc_profile_t *, sc_card_t *, int, sc_pkcs15_pin_info_t *, const u8 *, size_t, const u8 *, size_t); -static int myeid_puk_retries(sc_profile_t *, int); +static int myeid_puk_retries(sc_profile_t *profile, sc_pkcs15_pin_info_t *pin_info); + +static int acl_to_byte(const struct sc_acl_entry *e) +{ + switch (e->method) { + case SC_AC_NONE: + return 0x00; + case SC_AC_CHV: + case SC_AC_TERM: + case SC_AC_AUT: + if (e->key_ref == SC_AC_KEY_REF_NONE) + return 0x00; + if (e->key_ref < 1 || e->key_ref > MYEID_MAX_PINS) + return 0x00; + return e->key_ref; + case SC_AC_NEVER: + return 0x0F; + } + return 0x00; +} /* * Erase the card. @@ -52,17 +72,17 @@ static int myeid_puk_retries(sc_profile_t *, int); static int myeid_erase_card(sc_profile_t *profile, sc_card_t *card) { struct sc_cardctl_myeid_data_obj data_obj; - sc_pkcs15_pin_info_t pin_info; + sc_pkcs15_pin_info_t sopin_info, pin_info; + u8 data[8]; int r; - /* Just delete the entire MF */ + SC_FUNC_CALLED(card->ctx, 1); /* The SO pin has pin reference 1 -- not that it matters much * because pkcs15-init will ask to enter all pins, even if we * did a --so-pin on the command line. */ - sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info); - sc_keycache_set_pin_name(NULL, pin_info.reference, SC_PKCS15INIT_SO_PIN); + sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &sopin_info); /* Select parent DF and verify PINs/key as necessary */ r = sc_pkcs15init_authenticate(profile, card, profile->mf_info->file, SC_AC_OP_DELETE); @@ -71,23 +91,72 @@ static int myeid_erase_card(sc_profile_t *profile, sc_card_t *card) data[0]= 0xFF; data[1]= 0xFF; - data[2]= 0x33; + data[2]= 0x11; data[3]= 0x3F; data[4]= 0xFF; - data[5]= 0x33; - data[6]= 0x3F; + data[5]= 0x11; + data[6]= 0xFF; data[7]= 0xFF; + sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &pin_info); + if(pin_info.reference > 0 && pin_info.reference <= MYEID_MAX_PINS && + sopin_info.reference > 0 && sopin_info.reference <= MYEID_MAX_PINS) + { + data[2] = (pin_info.reference << 4)| pin_info.reference; + data[3] = (sopin_info.reference << 4) | 0x0F; + data[5] = data[2]; + } + data_obj.P1 = 0x01; data_obj.P2 = 0xE0; data_obj.Data = data; data_obj.DataLen = 0x08; + sc_debug(card->ctx, "so_pin(%d), user pin (%d)\n", + sopin_info.reference, pin_info.reference); + r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); - return r; + SC_FUNC_RETURN(card->ctx, 1, r); } +static int myeid_init_card(sc_profile_t *profile, + sc_card_t *card) +{ + struct sc_path path; + sc_file_t *file; + int r; + + SC_FUNC_CALLED(card->ctx, 1); + + sc_format_path("3F00", &path); + r = sc_select_file(card, &path, NULL); + + SC_FUNC_RETURN(card->ctx, 1, r); +} + +/* + * Create a DF + */ +static int myeid_create_dir(sc_profile_t *profile, sc_card_t *card, sc_file_t *df) +{ + int r=0; + struct sc_file *file; + + SC_FUNC_CALLED(card->ctx, 1); + if (!profile || !card || !df) + return SC_ERROR_INVALID_ARGUMENTS; + + sc_debug(card->ctx, "id (%x)\n",df->id); + + if(df->id == 0x5015) + { + sc_debug(card->ctx, "only Select (%x)\n",df->id); + r = sc_select_file(card, &df->path, NULL); + } + + SC_FUNC_RETURN(card->ctx, 1, r); +} /* * Select the PIN reference */ @@ -95,20 +164,27 @@ static int myeid_select_pin_reference(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_pin_info_t *pin_info) { sc_pkcs15_pin_info_t pin_info_prof; + int type; - pin_info_prof.reference = 1; /* Default SO PIN ref. */ - sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info_prof); - - /* For the SO pin, we take the first available pin reference = 1 */ + SC_FUNC_CALLED(card->ctx, 1); if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) - pin_info->reference = pin_info_prof.reference; - /* sc_pkcs15init_create_pin() starts checking if 0 is an acceptable - * pin reference, which isn't for the myeid cards. And since the - * value 1 has been assigned to the SO pin, we'll jump to 2. */ - else if (pin_info->reference == 0) - pin_info->reference = pin_info_prof.reference + 1; + { + type = SC_PKCS15INIT_SO_PIN; + sc_debug(card->ctx, "PIN_FLAG_SO_PIN, ref (%d), tries_left (%d)\n", + pin_info->reference,pin_info->tries_left); + } + else + { + type = SC_PKCS15INIT_USER_PIN; + sc_debug(card->ctx, "PIN_FLAG_PIN, ref (%d), tries_left (%d)\n", + pin_info->reference, pin_info->tries_left); - return 0; + } + + if (pin_info->reference <= 0 || pin_info->reference > MYEID_MAX_PINS) + pin_info->reference = 1; + + SC_FUNC_RETURN(card->ctx, 1, 0); } /* @@ -138,6 +214,7 @@ static int myeid_new_file(sc_profile_t *profile, sc_card_t *card, char name[64], *tag; int r; + SC_FUNC_CALLED(card->ctx, 1); if (type == SC_PKCS15_TYPE_PRKEY_RSA) tag = "private-key"; else if (type == SC_PKCS15_TYPE_PUBKEY_RSA) @@ -178,21 +255,23 @@ static int myeid_new_file(sc_profile_t *profile, sc_card_t *card, } *out = file; - return 0; + SC_FUNC_RETURN(card->ctx, 1, 0); } static int myeid_encode_private_key(sc_profile_t *profile, sc_card_t *card, struct sc_pkcs15_prkey_rsa *rsa, u8 *key, size_t *keysize, int key_ref) { - return 0; + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, 0); } static int myeid_encode_public_key(sc_profile_t *profile, sc_card_t *card, struct sc_pkcs15_prkey_rsa *rsa, u8 *key, size_t *keysize, int key_ref) { - return 0; + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, 0); } /* @@ -232,9 +311,13 @@ static int myeid_generate_store_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_prkey_info_t *info) { struct sc_cardctl_myeid_gen_store_key_info args; + struct sc_cardctl_myeid_data_obj data_obj; + unsigned char raw_pubkey[256]; int r; + unsigned int mod_len; sc_file_t *prkf = NULL; + SC_FUNC_CALLED(card->ctx, 1); /* Parameter check */ if ( (keybits < 1024) || (keybits > 2048) || (keybits & 0X7)) { sc_debug(card->ctx, @@ -303,7 +386,7 @@ done: if (prkf) sc_file_free(prkf); - return r; + SC_FUNC_RETURN(card->ctx, 1, r); } /* @@ -314,36 +397,30 @@ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card, const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len) { - u8 data[19]; + u8 data[20]; int so_pin_ref; - int r; + int r,type, puk_tries; struct sc_cardctl_myeid_data_obj data_obj; sc_file_t *pinfile = NULL; + SC_FUNC_CALLED(card->ctx, 1); + sc_debug(card->ctx, "pin (%d), pin_len (%d), puk_len(%d) \n", + pin_info->reference, pin_len, puk_len); + if (pin_info->reference >= MYEID_MAX_PINS) return SC_ERROR_INVALID_ARGUMENTS; if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4) return SC_ERROR_INVALID_PIN_LENGTH; - /* Verify required access rights if needed (i.e. if the - * pin file isn't in the CREATE life cycle state). */ - if (!ignore_ac) - { - /* Re-ink the SO pin to the MF because there is the pin file */ - so_pin_ref = sc_keycache_find_named_pin(&profile->df_info->file->path, - SC_PKCS15INIT_SO_PIN); - if (so_pin_ref >= 0) - sc_keycache_set_pin_name(&profile->mf_info->file->path, - so_pin_ref, SC_PKCS15INIT_SO_PIN); + if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) + type = SC_PKCS15INIT_SO_PIN; + else + type = SC_PKCS15INIT_USER_PIN; - r = sc_profile_get_file(profile, "pinfile", &pinfile); - if (r >= 0) - r = sc_pkcs15init_authenticate(profile, card, pinfile, SC_AC_OP_UPDATE); - sc_file_free(pinfile); - if (r < 0) - return r; - } + sc_debug(card->ctx, "pin type (%s)\n", + (type == SC_PKCS15INIT_SO_PIN) ? "SO_PIN": "USER_PIN"); + memset(data, 0xFF, sizeof(data)); /* Make command to add a pin-record */ data_obj.P1 = 01; data_obj.P2 = pin_info->reference; /* myeid pin number */ @@ -351,40 +428,40 @@ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card, memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin*/ memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */ - - /* Optional PIN locking - * data[17] = pin_info->tries_left & 0x0F; - * data[18] = myeid_puk_retries(profile, pin_info->reference) & 0x0F; - */ - + data[16] = 0x00; data[17] = 0x00; data[18] = 0x00; - data[19] = 0x00; /* FIXME, array is only 0..18 */ data_obj.Data = data; - data_obj.DataLen = 0x10; + data_obj.DataLen = 16; + + puk_tries = myeid_puk_retries(profile, pin_info); + if(pin_info->tries_left > 0 && pin_info->tries_left < 15 && + puk_tries > 0 && puk_tries < 15) + { + /* Optional PIN locking */ + data[16] = (pin_info->tries_left & 0x0F); + data[17] = (puk_tries & 0x0F); + data_obj.DataLen = 19; + } r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); - return r; + SC_FUNC_RETURN(card->ctx, 1, r); } -static int myeid_puk_retries(sc_profile_t *profile, int pin_ref) +static int myeid_puk_retries(sc_profile_t *profile, sc_pkcs15_pin_info_t *pin_info) { - sc_pkcs15_pin_info_t pin_info; + sc_pkcs15_pin_info_t puk_info; - pin_info.reference = 1; /* Default SO PIN ref. */ - sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &pin_info); - - /* If pin_ref is the SO PIN, get the SO PUK info, otherwise the User PUK info */ sc_profile_get_pin_info(profile, - pin_ref == pin_info.reference ? + (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) ? SC_PKCS15INIT_SO_PUK : SC_PKCS15INIT_USER_PUK, - &pin_info); + &puk_info); - if ((pin_info.tries_left < 0) || (pin_info.tries_left > 15)) - return 3; /* Little extra safety */ - return pin_info.tries_left; + if ((puk_info.tries_left < 0) || (puk_info.tries_left >= 15)) + return -1; + return puk_info.tries_left; } /* For Myeid, all objects are files that can be deleted in any order */ @@ -392,13 +469,14 @@ static int myeid_delete_object(struct sc_profile *profile, struct sc_card *card, unsigned int type, const void *data, const sc_path_t *path) { + SC_FUNC_CALLED(card->ctx, 1); return sc_pkcs15init_delete_by_path(profile, card, path); } static struct sc_pkcs15init_operations sc_pkcs15init_myeid_operations = { myeid_erase_card, - NULL, /* init_card */ - NULL, /* create_dir */ + myeid_init_card, /* init_card */ + myeid_create_dir, /* create_dir */ NULL, /* create_domain */ myeid_select_pin_reference, myeid_create_pin, diff --git a/src/pkcs15init/pkcs15-westcos.c b/src/pkcs15init/pkcs15-westcos.c index efcef804..65235d42 100644 --- a/src/pkcs15init/pkcs15-westcos.c +++ b/src/pkcs15init/pkcs15-westcos.c @@ -268,9 +268,9 @@ static int westcos_pkcs15init_generate_key(sc_profile_t *profile, #ifndef ENABLE_OPENSSL return SC_ERROR_NOT_SUPPORTED; #else - int r = SC_ERROR_UNKNOWN; - long lg; - char *p; + int r = SC_ERROR_UNKNOWN; + long lg; + u8 *p; sc_pkcs15_prkey_info_t *key_info = (sc_pkcs15_prkey_info_t *) obj->data; RSA *rsa = NULL; BIGNUM *bn = NULL; diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index cf4775c0..8e953735 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -62,9 +62,7 @@ static int new_pin = 0; static int debloque = 0; static char *get_filename = NULL; -static char *get_path = NULL; static char *put_filename = NULL; -static char *put_path = NULL; static int do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src) { @@ -90,7 +88,7 @@ static void print_openssl_erreur(void) fprintf(stderr, "%s\n", ERR_error_string(r, NULL)); } -static verify_pin(sc_card_t *card, int pin_reference, char *pin_value) +static int verify_pin(sc_card_t *card, int pin_reference, char *pin_value) { int r, tries_left = -1; struct sc_pin_cmd_data data; @@ -117,7 +115,7 @@ static verify_pin(sc_card_t *card, int pin_reference, char *pin_value) return SC_ERROR_INVALID_ARGUMENTS; } - data.pin1.data = pin_value; + data.pin1.data = (u8*)pin_value; data.pin1.len = strlen(pin_value); } @@ -140,7 +138,7 @@ static verify_pin(sc_card_t *card, int pin_reference, char *pin_value) return 0; } -static change_pin(sc_card_t *card, +static int change_pin(sc_card_t *card, int pin_reference, char *pin_value1, char *pin_value2) @@ -170,10 +168,10 @@ static change_pin(sc_card_t *card, return SC_ERROR_INVALID_ARGUMENTS; } - data.pin1.data = pin_value1; + data.pin1.data = (u8*)pin_value1; data.pin1.len = strlen(pin_value1); - data.pin2.data = pin_value2; + data.pin2.data = (u8*)pin_value2; data.pin2.len = strlen(pin_value2); } @@ -198,7 +196,7 @@ static change_pin(sc_card_t *card, return 0; } -static debloque_pin(sc_card_t *card, +static int debloque_pin(sc_card_t *card, int pin_reference, char *puk_value, char *pin_value) @@ -228,10 +226,10 @@ static debloque_pin(sc_card_t *card, return SC_ERROR_INVALID_ARGUMENTS; } - data.pin1.data = puk_value; + data.pin1.data = (u8*)puk_value; data.pin1.len = strlen(puk_value); - data.pin2.data = pin_value; + data.pin2.data = (u8*)pin_value; data.pin2.len = strlen(pin_value); } @@ -351,7 +349,7 @@ int main(int argc, char *argv[]) { int r; int i = 1; - u8 *p; + char *p; int card_presente = 0; sc_context_param_t ctx_param; sc_reader_t *lecteur = NULL; @@ -589,7 +587,7 @@ int main(int argc, char *argv[]) pin_cmd.encoding = SC_PIN_ENCODING_GLP; pin_cmd.len = strlen(pin); - pin_cmd.data = pin; + pin_cmd.data = (u8*)pin; pin_cmd.max_length = 8; ck.new_key.key_len = sc_build_pin(ck.new_key.key_value, @@ -613,7 +611,7 @@ int main(int argc, char *argv[]) puk_cmd.encoding = SC_PIN_ENCODING_GLP; puk_cmd.len = strlen(puk); - puk_cmd.data = puk; + puk_cmd.data = (u8*)puk; puk_cmd.max_length = 8; ck.new_key.key_len = sc_build_pin(ck.new_key.key_value, @@ -651,10 +649,11 @@ int main(int argc, char *argv[]) if(keylen) { - int lg; + size_t lg; struct sc_pkcs15_pubkey key; struct sc_pkcs15_pubkey_rsa *dst = &(key.u.rsa); - + u8 *pdata; + memset(&key, 0, sizeof(key)); key.algorithm = SC_ALGORITHM_RSA; @@ -687,7 +686,7 @@ int main(int argc, char *argv[]) #endif { fprintf(stderr, - "RSA_generate_key_ex return %d\n", ERR_get_error()); + "RSA_generate_key_ex return %ld\n", ERR_get_error()); goto out; } @@ -696,11 +695,11 @@ int main(int argc, char *argv[]) if(!i2d_RSAPrivateKey_bio(mem, rsa)) { fprintf(stderr, - "i2d_RSAPrivateKey_bio return %d\n", ERR_get_error()); + "i2d_RSAPrivateKey_bio return %ld\n", ERR_get_error()); goto out; } - lg = BIO_get_mem_data(mem, &p); + lg = BIO_get_mem_data(mem, &pdata); sc_format_path("0001", &path); r = sc_select_file(card, &path, NULL); @@ -750,7 +749,7 @@ int main(int argc, char *argv[]) printf("Private key length is %d\n", lg); printf("Write private key.\n"); - r = sc_update_binary(card,0,p,lg,0); + r = sc_update_binary(card,0,pdata,lg,0); if(r<0) goto out; printf("Private key correctly written.\n"); @@ -761,7 +760,7 @@ int main(int argc, char *argv[]) || !do_convert_bignum(&dst->exponent, rsa->e)) goto out; - r = sc_pkcs15_encode_pubkey(ctx, &key, &p, &lg); + r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg); if(r) goto out; printf("Public key length %d\n", lg); @@ -771,7 +770,7 @@ int main(int argc, char *argv[]) if(r) goto out; printf("Write public key.\n"); - r = sc_update_binary(card,0,p,lg,0); + r = sc_update_binary(card,0,pdata,lg,0); if(r<0) goto out; printf("Public key correctly written.\n"); @@ -779,9 +778,10 @@ int main(int argc, char *argv[]) if(cert) { - BIO *bio; - X509 *xp; - + BIO *bio; + X509 *xp; + u8 *pdata; + bio = BIO_new(BIO_s_file()); if (BIO_read_filename(bio, cert) <= 0) { @@ -798,7 +798,7 @@ int main(int argc, char *argv[]) } else { - int lg = cert2der(xp, &p); + int lg = cert2der(xp, &pdata); sc_format_path("0002", &path); r = sc_select_file(card, &path, NULL); @@ -807,14 +807,14 @@ int main(int argc, char *argv[]) /* FIXME: verifier taille fichier compatible... */ printf("Write certificate %s.\n", cert); - r = sc_update_binary(card,0,p,lg,0); + r = sc_update_binary(card,0,pdata,lg,0); if(r<0) { - if(p) free(p); + if(pdata) free(pdata); goto out; } if(xp) X509_free(xp); - if(p) free(p); + if(pdata) free(pdata); printf("Certificate correctly written.\n"); } @@ -950,5 +950,6 @@ out: if (ctx) sc_release_context(ctx); + return EXIT_SUCCESS; } From 450e1fc5aeab264da8aa671ac90730d28b6ae497 Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 5 Nov 2009 18:27:56 +0000 Subject: [PATCH 37/57] Merge [3794:3803/trunk] git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3804 c6295689-39f2-0310-b995-f0e70906c6a9 --- configure.ac | 8 +- src/libopensc/card-oberthur.c | 418 +-------------------- src/pkcs11/framework-pkcs15.c | 28 ++ src/pkcs11/openssl.c | 3 +- src/pkcs15init/pkcs15-oberthur.c | 619 +------------------------------ 5 files changed, 49 insertions(+), 1027 deletions(-) diff --git a/configure.ac b/configure.ac index ef1c60b1..72a4d34e 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ AC_PREREQ(2.60) define([PACKAGE_VERSION_MAJOR], [0]) define([PACKAGE_VERSION_MINOR], [12]) define([PACKAGE_VERSION_FIX], [0]) -define([PACKAGE_SUFFIX], [-svn-mp]) +define([PACKAGE_SUFFIX], [-svn]) AC_INIT([opensc],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX]) AC_CONFIG_AUX_DIR([.]) @@ -153,9 +153,9 @@ AC_ARG_ENABLE( AC_ARG_ENABLE( [pcsc], - [AS_HELP_STRING([--enable-pcsc],[enable pcsc support @<:@disabled@:>@])], + [AS_HELP_STRING([--disable-pcsc],[disable pcsc support @<:@enabled@:>@])], , - [enable_pcsc="no"] + [enable_pcsc="yes"] ) AC_ARG_ENABLE( @@ -587,7 +587,7 @@ if test "${enable_pcsc}" = "yes"; then DEFAULT_PCSC_PROVIDER="winscard.dll" ;; *) - DEFAULT_PCSC_PROVIDER="/usr/lib${libdir##*/lib}/libpcsclite.so" + DEFAULT_PCSC_PROVIDER="libpcsclite.so.1" ;; esac else diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index 79471989..fab3a3b1 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -3,7 +3,8 @@ * CosmopolIC v5; * * Copyright (C) 2001, 2002 Juha Yrjölä - * Copyright (C) 2003 Viktor Tarasov , idealx + * Copyright (C) 2009 Viktor Tarasov , + * OpenTrust * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -43,8 +44,6 @@ #define DES_ecb_encrypt(a,b,c,d) des_ecb_encrypt(a,b,*c,d) #endif -#define NOT_YET 1 - static struct sc_atr_table oberthur_atrs[] = { { "3B:7D:18:00:00:00:31:80:71:8E:64:77:E3:01:00:82:90:00", NULL, "Oberthur 64k v4/2.1.1", SC_CARD_TYPE_OBERTHUR_64K, 0, NULL }, @@ -126,39 +125,6 @@ static int auth_get_serialnr(sc_card_t *card, sc_serial_number_t *serial); static int auth_select_file(sc_card_t *card, const sc_path_t *in_path, sc_file_t **file_out); -#ifndef NOT_YET -static int auth_sm_init (struct sc_card *card, struct sc_sm_info *sm_info, - int cmd, unsigned char *id, size_t id_len, - unsigned char *resp, size_t *resp_len); -static int auth_sm_execute (struct sc_card *card, struct sc_sm_info *sm_info, - unsigned char *data, int data_len, unsigned char *out, size_t len); -static int auth_sm_update_rsa (struct sc_card *card, - struct sc_cardctl_oberthur_updatekey_info *data); -static int auth_sm_reset_pin (struct sc_card *card, int type, int ref, - const unsigned char *data, size_t len); -static int auth_sm_read_binary (struct sc_card *card, - unsigned char *id, size_t id_len, - size_t offs, unsigned char *out, size_t len); -static int auth_sm_release (struct sc_card *card, struct sc_sm_info *sm_info, - unsigned char *data, int data_len); -#endif - -#if 0 -/* this function isn't used anywhere */ -static void _auth_print_acls(struct sc_card *card, struct sc_file *file) -{ - int ii, jj; - - for (jj=0; jj < SC_MAX_AC_OPS; jj++) { - const sc_acl_entry_t *acl = sc_file_get_acl_entry(file, jj); - - for (ii=0; acl; acl = acl->next, ii++) { - sc_debug(card->ctx, "%i-%i: acl : meth 0x%X, ref 0x%X", - jj, ii, acl->method, acl->key_ref); - } - } -} -#endif static int auth_finish(sc_card_t *card) @@ -443,42 +409,20 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, add_acl_entry(card, file, SC_AC_OP_CRYPTO, attr[1]); add_acl_entry(card, file, SC_AC_OP_LIST_FILES, attr[2]); add_acl_entry(card, file, SC_AC_OP_DELETE, attr[3]); -#ifndef NOT_YET - add_acl_entry(card, file, SC_AC_OP_PIN_SET, attr[4]); - add_acl_entry(card, file, SC_AC_OP_PIN_CHANGE, attr[5]); - add_acl_entry(card, file, SC_AC_OP_PIN_RESET, attr[6]); -#endif } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { /* EF */ switch (file->ef_structure) { case SC_CARDCTL_OBERTHUR_KEY_DES: add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[0]); -#if 0 - add_acl_entry(card, file, SC_AC_OP_DECRYPT, attr[1]); - add_acl_entry(card, file, SC_AC_OP_ENCRYPT, attr[2]); - add_acl_entry(card, file, SC_AC_OP_CHECKSUM, attr[3]); - add_acl_entry(card, file, SC_AC_OP_VERIFY, attr[4]); -#else add_acl_entry(card, file, SC_AC_OP_READ, attr[1]); -#endif break; case SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC: add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[0]); -#if 0 - add_acl_entry(card, file, SC_AC_OP_ENCRYPT, attr[2]); - add_acl_entry(card, file, SC_AC_OP_VERIFY, attr[4]); -#else add_acl_entry(card, file, SC_AC_OP_READ, attr[2]); -#endif break; case SC_CARDCTL_OBERTHUR_KEY_RSA_CRT: add_acl_entry(card, file, SC_AC_OP_UPDATE, attr[0]); -#if 0 - add_acl_entry(card, file, SC_AC_OP_DECRYPT, attr[1]); - add_acl_entry(card, file, SC_AC_OP_SIGN, attr[3]); -#else add_acl_entry(card, file, SC_AC_OP_READ, attr[1]); -#endif break; } } @@ -889,15 +833,9 @@ encode_file_structure_V5(sc_card_t *card, const sc_file_t *file, ops[1] = SC_AC_OP_CRYPTO; ops[2] = SC_AC_OP_LIST_FILES; ops[3] = SC_AC_OP_DELETE; -#ifndef NOT_YET - ops[4] = SC_AC_OP_PIN_SET; /* SC_AC_OP_SET_REFERENCE */ - ops[5] = SC_AC_OP_PIN_CHANGE; /* SC_AC_OP_CHANGE_REFERENCE */ - ops[6] = SC_AC_OP_PIN_RESET; /* SC_AC_OP_RESET_COUNTER */ -#else ops[4] = SC_AC_OP_LIST_FILES; /* SC_AC_OP_SET_REFERENCE */ ops[5] = SC_AC_OP_LIST_FILES; /* SC_AC_OP_CHANGE_REFERENCE */ ops[6] = SC_AC_OP_LIST_FILES; /* SC_AC_OP_RESET_COUNTER */ -#endif } else if (file->type == SC_FILE_TYPE_WORKING_EF) { if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { @@ -1265,13 +1203,6 @@ auth_get_default_key(sc_card_t *card, struct sc_cardctl_default_key *data) { int rv = SC_ERROR_NO_DEFAULT_KEY; -#ifndef NOT_YET - if (data->method == SC_AC_PRO) { - card->sm_level = data->key_ref | 0x60; - rv = SC_SUCCESS; - } -#endif - SC_FUNC_RETURN(card->ctx, 1, rv); } @@ -1304,9 +1235,6 @@ auth_generate_key(sc_card_t *card, int use_sm, u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; sc_path_t tmp_path; int rv = 0; -#ifndef NOT_YET - const sc_acl_entry_t *entry; -#endif SC_FUNC_CALLED(card->ctx, 1); if (data->key_bits < 512 || data->key_bits > 2048 || @@ -1336,46 +1264,10 @@ auth_generate_key(sc_card_t *card, int use_sm, apdu.data = sbuf; apdu.datalen = rv + 4; -#ifndef NOT_YET - entry = sc_file_get_acl_entry(auth_current_df, SC_AC_OP_CRYPTO); - if (entry && entry->method == SC_AC_PRO) - if (card->sm_level < (entry->key_ref | 0x60)) - card->sm_level = entry->key_ref | 0x60; - - if (card->sm_level) { - struct sc_sm_info sm_info; - unsigned char init_data[SC_MAX_APDU_BUFFER_SIZE]; - int init_data_len = sizeof(init_data); - unsigned char out[SC_MAX_APDU_BUFFER_SIZE]; - int out_len = sizeof(init_data); - - rv = auth_sm_init (card, &sm_info, SC_SM_CMD_TYPE_GENERATE_RSA, - card->serialnr.value, card->serialnr.len, - init_data, &init_data_len); - SC_TEST_RET(card->ctx, rv, "SM: init failed"); - - sm_info.p1 = data->key_bits; - sm_info.data = apdu.data; - sm_info.data_len = apdu.datalen; - - rv = auth_sm_execute (card, &sm_info, init_data, init_data_len, - out, out_len); - SC_TEST_RET(card->ctx, rv, "SM: execute failed"); - - rv = auth_sm_release (card, &sm_info, out, out_len); - SC_TEST_RET(card->ctx, rv, "SM: release failed"); - - /* TODO clean resp */ - } - else { -#endif - rv = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, rv, "Card returned error"); -#ifndef NOT_YET - } -#endif + rv = sc_transmit_apdu(card, &apdu); + SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); + rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + SC_TEST_RET(card->ctx, rv, "Card returned error"); tmp_path.type = SC_PATH_TYPE_FILE_ID; tmp_path.len = 2; @@ -1500,19 +1392,6 @@ auth_update_key(sc_card_t *card, struct sc_cardctl_oberthur_updatekey_info *info SC_FUNC_CALLED(card->ctx, 1); -#ifndef NOT_YET - if (auth_current_ef) { - const sc_acl_entry_t *entry = sc_file_get_acl_entry(auth_current_ef, - SC_AC_OP_UPDATE); - - if (entry && entry->method == SC_AC_PRO) - if (card->sm_level < (entry->key_ref | 0x60)) - card->sm_level = entry->key_ref | 0x60; - } - - if (card->sm_level) - return auth_sm_update_rsa(card, info); -#endif if (info->data_len != sizeof(void *) || !info->data) SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); @@ -1798,9 +1677,6 @@ auth_reset_retry_counter(sc_card_t *card, unsigned int type, size_t len; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; struct sc_pin_cmd_pin pin_info, puk_info; -#ifndef NOT_YET - const sc_acl_entry_t *entry; -#endif SC_FUNC_CALLED(card->ctx, 1); rv = auth_get_pin_reference (card, type, ref, SC_PIN_CMD_CHANGE, &pin_ref); @@ -1816,15 +1692,6 @@ auth_reset_retry_counter(sc_card_t *card, unsigned int type, if (puklen > puk_info.pad_length || pinlen > pin_info.pad_length) SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); -#ifndef NOT_YET - entry = sc_file_get_acl_entry(auth_current_df, SC_AC_OP_PIN_RESET); - if (entry && entry->method == SC_AC_PRO) { - card->sm_level = entry->key_ref | 0x60; - rv = auth_sm_reset_pin(card, type, ref, pin, pinlen); - - SC_FUNC_RETURN(card->ctx, 1, rv); - } -#endif memset(sbuf, puk_info.pad_char, puk_info.pad_length); memcpy(sbuf, puk, puklen); len = puk_info.pad_length; @@ -2043,32 +1910,12 @@ auth_read_binary(sc_card_t *card, unsigned int offset, u8 *buf, size_t count, unsigned long flags) { int rv; -#ifndef NOT_YET - const sc_acl_entry_t *entry; -#endif SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx,"offset %i; size %i; flags 0x%lX\n", offset, count, flags); sc_debug(card->ctx,"last selected : magic %X; ef %X\n", auth_current_ef->magic, auth_current_ef->ef_structure); -/* _auth_print_acls(card, auth_current_ef); */ - -#ifndef NOT_YET - entry = sc_file_get_acl_entry(auth_current_ef, SC_AC_OP_READ); - sc_debug(card->ctx,"entry %p; %i\n", entry, SC_AC_OP_READ); - if (entry && entry->method == SC_AC_PRO) { - sc_debug(card->ctx, "needs SM level 0x%X\n", entry->key_ref >> 3); - - card->sm_level = entry->key_ref | 0x60; - rv = auth_sm_read_binary(card, - auth_current_ef->path.value, auth_current_ef->path.len, - offset, buf, count); - - sc_debug(card->ctx, "rv %i\n", rv); - SC_FUNC_RETURN(card->ctx, 1, rv); - } -#endif if (offset & ~0x7FFF) SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid file offset"); @@ -2205,259 +2052,6 @@ auth_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS); } -#ifndef NOT_YET -static int -auth_sm_init (struct sc_card *card, struct sc_sm_info *sm_info, int cmd, - unsigned char *id, size_t id_len, - unsigned char *resp, size_t *resp_len) -{ - int rv; - struct sc_apdu apdu; - unsigned char host_challenge[8]; - int host_challenge_len = sizeof(host_challenge); - - sc_debug(card->ctx, "called; command 0x%X\n", cmd); - if (!card || !sm_info || !id || !id_len || !resp || !resp_len) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - - if (!card->sm.funcs.initialize || !card->sm.funcs.get_apdus) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); - - if ((card->sm_level & 0xE0) != 0x60) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - - if (id_len > sizeof(sm_info->id)) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - - if (*resp_len < 28) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - - memset(sm_info, 0, sizeof(*sm_info)); - - sm_info->index = 0; - sm_info->version = 1; - sm_info->cmd = cmd; - sm_info->level = (card->sm_level & 0x18) >> 3; - - sm_info->id_len = id_len; - memcpy(sm_info->id, id, id_len); - - sm_info->status = 0; - - sm_info->serialnr = card->serialnr; - - rv = card->sm.funcs.initialize(card->ctx, sm_info, - host_challenge, &host_challenge_len); - SC_TEST_RET(card->ctx, rv, "SM: INITIALIZE failed"); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x50, - sm_info->version, sm_info->index); - apdu.cla = 0x80; - apdu.resp = resp; - apdu.resplen = *resp_len; - apdu.lc = 8; - apdu.le = 12; - apdu.data = host_challenge; - apdu.datalen = 8; - - rv=sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, rv, "transmit APDU failed"); - - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, rv, "Card returned error"); - - if (apdu.resplen != 28) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL); - - *resp_len = 28; - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - - -static int -auth_sm_execute (struct sc_card *card, struct sc_sm_info *sm_info, - unsigned char *data, int data_len, - unsigned char *out, size_t len) -{ -#define AUTH_SM_APDUS_MAX 6 - int rv, ii; - struct sc_apdu apdus[AUTH_SM_APDUS_MAX]; - unsigned char sbufs[AUTH_SM_APDUS_MAX][SC_MAX_APDU_BUFFER_SIZE]; - unsigned char rbufs[AUTH_SM_APDUS_MAX][SC_MAX_APDU_BUFFER_SIZE]; - int nn_apdus = AUTH_SM_APDUS_MAX; - - if (!card->sm.funcs.initialize || !card->sm.funcs.get_apdus) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); - - memset(&apdus, 0, sizeof(apdus)); - memset(&sbufs, 0, sizeof(sbufs)); - memset(&rbufs, 0, sizeof(rbufs)); - for (ii=0; iism.funcs.get_apdus(card->ctx, sm_info, - data, data_len, apdus, &nn_apdus); - SC_TEST_RET(card->ctx, rv, "SM: GET_APDUS failed"); - - sc_debug(card->ctx, "GET_APDUS: rv %i; nn cmds %i\n", - rv, nn_apdus); - - for (ii=0; ii < nn_apdus; ii++) { - rv = sc_transmit_apdu(card, &apdus[ii]); - if (rv < 0) - break; - - rv = sc_check_sw(card, apdus[ii].sw1, apdus[ii].sw2); - if (rv < 0) - break; - } - - if (rv) { - sm_info->status = rv; - auth_sm_release (card, sm_info, NULL, 0); - } - - if (out && len > 0 && !rv) { - if (len > apdus[nn_apdus-1].resplen) - len = apdus[nn_apdus-1].resplen; - - memcpy(out, apdus[nn_apdus-1].resp, len); - SC_FUNC_RETURN(card->ctx, 1, len); - } - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - - -static int -auth_sm_release (struct sc_card *card, struct sc_sm_info *sm_info, - unsigned char *data, int data_len) -{ - int rv; - struct sc_apdu apdu; - - card->sm_level = 0; - - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2E, 0x00, 0x60); - apdu.cla = 0x80; - apdu.lc = 0x0; - apdu.le = 0x0; - apdu.resplen = 0; - apdu.resp = NULL; - - rv = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); - - if (sm_info && card->sm.funcs.finalize) { - rv = card->sm.funcs.finalize(card->ctx, sm_info, data, data_len); - SC_TEST_RET(card->ctx, rv, "SM: finalize failed"); - } - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - - -static int -auth_sm_update_rsa (struct sc_card *card, - struct sc_cardctl_oberthur_updatekey_info *update_info) -{ - int rv, rvv; - struct sc_sm_info sm_info; - unsigned char init_data[SC_MAX_APDU_BUFFER_SIZE]; - int init_data_len = sizeof(init_data); - - sc_debug(card->ctx, "called; SM Level 0x%X\n", card->sm_level); - if (!update_info || !card->sm_level) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - - /* If rsa defined, we impose Mosilla style ID. */ - if (update_info->data && (update_info->data_len == sizeof(void *))) { - struct sc_pkcs15_prkey_rsa *rsa = (struct sc_pkcs15_prkey_rsa *)update_info->data; - - SHA1(rsa->modulus.data, rsa->modulus.len, update_info->id); - update_info->id_len = SHA_DIGEST_LENGTH; - } - - rv = auth_sm_init (card, &sm_info, SC_SM_CMD_TYPE_UPDATE_RSA, - update_info->id, update_info->id_len, init_data, &init_data_len); - if (!rv) - rv = auth_sm_execute (card, &sm_info, - init_data, init_data_len, NULL, 0); - - rvv = auth_sm_release (card, &sm_info, NULL, 0); - - SC_FUNC_RETURN(card->ctx, 1, (rv ? rv : rvv)); -} - - -static int -auth_sm_reset_pin (struct sc_card *card, int type, int ref, - const u8 *data, size_t len) -{ - int rv; - struct sc_sm_info sm_info; - unsigned char init_data[SC_MAX_APDU_BUFFER_SIZE]; - int init_data_len = sizeof(init_data); - - sc_debug(card->ctx, "called; PIN ref 0x%X; data length %i\n", ref, len); - - rv = auth_sm_init (card, &sm_info, SC_SM_CMD_TYPE_RESET_PIN, - card->serialnr.value, card->serialnr.len, init_data, &init_data_len); - SC_TEST_RET(card->ctx, rv, "SM: init failed"); - - sm_info.p1 = ref; - sm_info.data = data; - sm_info.data_len = len; - - rv = auth_sm_execute (card, &sm_info, init_data, init_data_len, NULL, 0); - SC_TEST_RET(card->ctx, rv, "SM: execute failed"); - - rv = auth_sm_release (card, &sm_info, NULL, 0); - SC_TEST_RET(card->ctx, rv, "SM: release failed"); - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - - -static int -auth_sm_read_binary (struct sc_card *card, unsigned char *id, size_t id_len, - size_t offs, unsigned char *out, size_t len) -{ - int rv; - struct sc_sm_info sm_info; - unsigned char init_data[SC_MAX_APDU_BUFFER_SIZE]; - int init_data_len = sizeof(init_data); - - sc_debug(card->ctx, "called; offs %i; len %i\n", offs, len); - - if (len > 0xF0) { - sc_debug(card->ctx, "Not yet: reading length cannot be more then 240 bytes."); - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); - } - - rv = auth_sm_init (card, &sm_info, SC_SM_CMD_TYPE_READ_BINARY, - id, id_len, init_data, &init_data_len); - SC_TEST_RET(card->ctx, rv, "SM: init failed"); - - sm_info.p1 = offs; - sm_info.p2 = len; - - rv = auth_sm_execute (card, &sm_info, init_data, init_data_len, out, len); - SC_TEST_RET(card->ctx, rv, "SM: execute failed"); - - len = rv; - - rv = auth_sm_release (card, &sm_info, out, len); - SC_TEST_RET(card->ctx, rv, "SM: release failed"); - - SC_FUNC_RETURN(card->ctx, 1, len); -} -#endif - static struct sc_card_driver * sc_get_driver(void) { diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index bcbcec2a..cf47e19e 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -184,6 +184,7 @@ static CK_RV pkcs15_unbind(struct sc_pkcs11_card *p11card) unlock_card(fw_data); rc = sc_pkcs15_unbind(fw_data->p15_card); + free(fw_data); return sc_to_cryptoki_error(rc, p11card->reader); } @@ -262,6 +263,24 @@ __pkcs15_release_object(struct pkcs15_any_object *obj) return 0; } +static int +__pkcs15_delete_object(struct pkcs15_fw_data *fw_data, struct pkcs15_any_object *obj) +{ + unsigned int i; + + if (fw_data->num_objects == 0) + return SC_ERROR_INTERNAL; + + for (i = 0; i < fw_data->num_objects; ++i) + if (fw_data->objects[i] == obj) { + fw_data->objects[i] = fw_data->objects[--fw_data->num_objects]; + if (__pkcs15_release_object(obj) > 0) + return SC_ERROR_INTERNAL; + return SC_SUCCESS; + } + return SC_ERROR_OBJECT_NOT_FOUND; +} + static int public_key_created(struct pkcs15_fw_data *fw_data, const unsigned int num_objects, const u8 *id, @@ -917,6 +936,7 @@ static CK_RV pkcs15_create_tokens(struct sc_pkcs11_card *p11card) static CK_RV pkcs15_release_token(struct sc_pkcs11_card *p11card, void *fw_token) { unlock_card((struct pkcs15_fw_data *) p11card->fw_data); + free(fw_token); return CKR_OK; } @@ -2679,6 +2699,14 @@ static CK_RV pkcs15_dobj_destroy(struct sc_pkcs11_session *session, void *object /* Delete object in smartcard */ rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object); + /* FIXME: PIN revalidation missing, following belongs libopensc */ + if (rv >= 0) { + /* pool_find_and_delete is called, therefore correct refcont + * Oppose to pkcs15_add_object */ + --((struct pkcs15_any_object*)object)->refcount; + /* Delete object in pkcs15 */ + rv = __pkcs15_delete_object(fw_data, (struct pkcs15_any_object*)object); + } sc_pkcs15init_unbind(profile); sc_unlock(card->card); diff --git a/src/pkcs11/openssl.c b/src/pkcs11/openssl.c index 786329d6..3da5177c 100644 --- a/src/pkcs11/openssl.c +++ b/src/pkcs11/openssl.c @@ -390,6 +390,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, pad = RSA_NO_PADDING; break; default: + EVP_PKEY_free(pkey); return CKR_ARGUMENTS_BAD; } @@ -400,7 +401,7 @@ CK_RV sc_pkcs11_verify_data(const unsigned char *pubkey, int pubkey_len, rsa_out = (unsigned char *) malloc(RSA_size(rsa)); if (rsa_out == NULL) { - free(rsa); + RSA_free(rsa); return CKR_DEVICE_MEMORY; } diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 6d85d7c9..437e96c2 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -2,8 +2,8 @@ * Oberthur specific operation for PKCS #15 initialization * * Copyright (C) 2002 Juha Yrjölä - * Copyright (C) 2003 Idealx - * Viktor Tarasov + * Copyright (C) 2009 Viktor Tarasov , + * OpenTrust * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -46,17 +46,6 @@ #define COSM_TITLE "OberthurAWP" -#define COSM_TLV_TAG 0x00 -#define COSM_LIST_TAG 0xFF -#define COSM_TAG_CONTAINER 0x0000 -#define COSM_TAG_CERT 0x0001 -#define COSM_TAG_PRVKEY_RSA 0x04B1 -#define COSM_TAG_PUBKEY_RSA 0x0349 -#define COSM_TAG_DES 0x0679 -#define COSM_TAG_DATA 0x0001 -#define COSM_IMPORTED 0x0000 -#define COSM_GENERATED 0x0004 - #define TLV_TYPE_V 0 #define TLV_TYPE_LV 1 #define TLV_TYPE_TLV 2 @@ -64,15 +53,9 @@ /* Should be greater then SC_PKCS15_TYPE_CLASS_MASK */ #define SC_DEVICE_SPECIFIC_TYPE 0x1000 -#define COSM_PUBLIC_LIST (SC_DEVICE_SPECIFIC_TYPE | 0x02) -#define COSM_PRIVATE_LIST (SC_DEVICE_SPECIFIC_TYPE | 0x03) -#define COSM_CONTAINER_LIST (SC_DEVICE_SPECIFIC_TYPE | 0x04) -#define COSM_TOKENINFO (SC_DEVICE_SPECIFIC_TYPE | 0x05) - #define COSM_TYPE_PRKEY_RSA (SC_DEVICE_SPECIFIC_TYPE | SC_PKCS15_TYPE_PRKEY_RSA) #define COSM_TYPE_PUBKEY_RSA (SC_DEVICE_SPECIFIC_TYPE | SC_PKCS15_TYPE_PUBKEY_RSA) -#define NOT_YET 1 static int cosm_update_pin(struct sc_profile *profile, sc_card_t *card, struct sc_pkcs15_pin_info *info, const u8 *pin, size_t pin_len, @@ -142,7 +125,7 @@ static int cosm_erase_card(struct sc_profile *profile, sc_card_t *card) } sc_debug(card->ctx, "erase file ddf %04X\n",df->id); - rv=cosm_delete_file(card, profile, df); + rv = cosm_delete_file(card, profile, df); if (sc_profile_get_file(profile, "private-DF", &dir) >= 0) { sc_debug(card->ctx, "erase file dir %04X\n",dir->id); @@ -170,8 +153,8 @@ static int cosm_erase_card(struct sc_profile *profile, sc_card_t *card) done: sc_keycache_forget_key(NULL, -1, -1); - if (rv==SC_ERROR_FILE_NOT_FOUND) - rv=0; + if (rv == SC_ERROR_FILE_NOT_FOUND) + rv = 0; SC_FUNC_RETURN(card->ctx, 1, rv); } @@ -604,14 +587,6 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card, memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3); memcpy(pubkey->u.rsa.modulus.data, args.pubkey, args.pubkey_len); -#ifndef NOT_YET - rv = sc_pkcs15_encode_pubkey(card->ctx, pubkey, &info->value.value, &info->value.len); - sc_debug(card->ctx, "rv %i\n",rv); - if (rv) { - sc_debug(card->ctx, "rv %i\n", rv); - goto failed; - } -#endif info->key_reference = 1; info->path = prkf->path; @@ -640,14 +615,11 @@ cosm_new_key(struct sc_profile *profile, sc_card_t *card, struct sc_pkcs15_prkey *key, unsigned int idx, struct sc_pkcs15_prkey_info *info) { - sc_file_t *prvfile = NULL; + struct sc_file *prvfile = NULL; struct sc_pkcs15_prkey_rsa *rsa = NULL; -#ifndef NOT_YET - sc_pkcs15_pubkey_t pubkey; -#endif - int rv; - char pbuf[SC_MAX_PATH_STRING_SIZE]; struct sc_cardctl_oberthur_updatekey_info update_info; + char pbuf[SC_MAX_PATH_STRING_SIZE]; + int rv; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "index %i; id %s\n", idx, sc_pkcs15_print_id(&info->id)); @@ -671,7 +643,7 @@ cosm_new_key(struct sc_profile *profile, sc_card_t *card, rv = sc_select_file(card, &prvfile->path, NULL); sc_debug(card->ctx, "rv %i", rv); - if (rv==SC_ERROR_FILE_NOT_FOUND) { + if (rv == SC_ERROR_FILE_NOT_FOUND) { sc_debug(card->ctx, "Before create file"); rv = sc_pkcs15init_create_file(profile, card, prvfile); } @@ -704,573 +676,12 @@ cosm_new_key(struct sc_profile *profile, sc_card_t *card, info->path = prvfile->path; info->modulus_length = rsa->modulus.len << 3; -#ifndef NOT_YET - /* extract public key */ - pubkey.algorithm = SC_ALGORITHM_RSA; - pubkey.u.rsa.modulus.len = rsa->modulus.len; - pubkey.u.rsa.modulus.data = (u8 *) malloc(rsa->modulus.len); - if (!pubkey.u.rsa.modulus.data) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_MEMORY_FAILURE); - - pubkey.u.rsa.exponent.len = rsa->exponent.len; - pubkey.u.rsa.exponent.data = (u8 *) malloc(rsa->exponent.len); - if (!pubkey.u.rsa.exponent.data) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_MEMORY_FAILURE); - - memcpy(pubkey.u.rsa.exponent.data, rsa->exponent.data, rsa->exponent.len); - memcpy(pubkey.u.rsa.modulus.data, rsa->modulus.data, rsa->modulus.len); - - rv = sc_pkcs15_encode_pubkey(card->ctx, &pubkey, &info->value.value, &info->value.len); - SC_TEST_RET(card->ctx, rv, "Update RSA: encode public key failed"); - - free(pubkey.u.rsa.modulus.data); - free(pubkey.u.rsa.exponent.data); -#endif - if (prvfile) sc_file_free(prvfile); SC_FUNC_RETURN(card->ctx, 1, rv); } -#ifdef COSM_EXTENDED -static int -cosm_delete_object (struct sc_profile *profile, struct sc_card *card, - unsigned int type, const void *data, const sc_path_t *path) -{ - struct sc_file *file = sc_file_new(); - int rv; - - SC_FUNC_CALLED(card->ctx, 1); - file->type = SC_FILE_TYPE_WORKING_EF; - file->ef_structure = SC_FILE_EF_TRANSPARENT; - file->id = path->value[path->len-2] * 0x100 + path->value[path->len-1]; - memcpy(&file->path, path, sizeof(file->path)); - - rv = cosm_delete_file(card, profile, file); - - sc_file_free(file); - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - -static int -cosm_path_to_index (struct sc_pkcs15_object *object, int *index, sc_pkcs15_der_t *out_der) -{ - struct sc_path path; - sc_pkcs15_der_t der; - - if (!object || !index || !out_der) - return SC_ERROR_INVALID_ARGUMENTS; - - switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) { - case SC_PKCS15_TYPE_PRKEY: - path = ((struct sc_pkcs15_prkey_info *)object->data)->path; - der = ((struct sc_pkcs15_prkey_info *)object->data)->value; - break; - case SC_PKCS15_TYPE_PUBKEY: - path = ((struct sc_pkcs15_pubkey_info *)object->data)->path; - der = ((struct sc_pkcs15_pubkey_info *)object->data)->value; - break; - case SC_PKCS15_TYPE_CERT: - path = ((struct sc_pkcs15_cert_info *)object->data)->path; - der = ((struct sc_pkcs15_cert_info *)object->data)->value; - break; - case SC_PKCS15_TYPE_DATA_OBJECT: - path = ((struct sc_pkcs15_data_info *)object->data)->path; - der = ((struct sc_pkcs15_data_info *)object->data)->value; - break; - default: - return SC_ERROR_INTERNAL; - - } - - out_der->value = der.value; - out_der->len = der.len; - *index = path.value[path.len-1] & 0xFF; - - return SC_SUCCESS; -} - - -static int -cosm_set_id (struct sc_context *ctx, struct sc_pkcs15_object *object, - unsigned char *in, int in_len) -{ - struct sc_pkcs15_id *id; - - SC_FUNC_CALLED(ctx, 1); - sc_debug(ctx, "in_len %i, type 0x%X\n", in_len, object->type); - if (!object || !in || !in_len || in_len > SC_PKCS15_MAX_ID_SIZE) - return SC_ERROR_INVALID_ARGUMENTS; - - switch (object->type & SC_PKCS15_TYPE_CLASS_MASK) { - case SC_PKCS15_TYPE_PRKEY: - id = &((struct sc_pkcs15_prkey_info *)object->data)->id; - break; - case SC_PKCS15_TYPE_PUBKEY: - id = &((struct sc_pkcs15_pubkey_info *)object->data)->id; - break; - case SC_PKCS15_TYPE_CERT: - id = &((struct sc_pkcs15_cert_info *)object->data)->id; - break; - case SC_PKCS15_TYPE_DATA_OBJECT: - id = &((struct sc_pkcs15_data_info *)object->data)->id; - break; - default: - return SC_ERROR_INTERNAL; - - } - - memcpy(id->value, in, in_len); - id->len = in_len; - - sc_debug(ctx, "id %s\n", sc_pkcs15_print_id(id)); - SC_FUNC_RETURN(ctx, 1, SC_SUCCESS); -} - - -static int -cosm_update_df_delete_object(struct sc_pkcs15_card *p15card, - struct sc_profile *profile, - struct sc_pkcs15_object *object) -{ - int rv; - - SC_FUNC_CALLED(p15card->card->ctx, 1); - - rv = cosm_ext_remove_data (profile, p15card->card, object); - - SC_FUNC_RETURN(p15card->card->ctx, 1, rv); -} - - -static int -cosm_update_df_new_object(struct sc_pkcs15_card *p15card, - struct sc_profile *profile, - struct sc_pkcs15_object *object) -{ - struct sc_pkcs15_pubkey pubkey; - struct sc_pkcs15_der der; - struct sc_pkcs15_tokeninfo tokeninfo; - struct cosm_key_info ikey; - struct cosm_cert_info icert; - struct cosm_data_info idata; - struct sc_card *card = p15card->card; - struct sc_file *info_file=NULL, *obj_file=NULL; - int index, prvkey_id, rv; - - SC_FUNC_CALLED(card->ctx, 1); - if (!p15card || !profile) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - else if (!object) - SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS); - - if (object->type == SC_PKCS15_TYPE_AUTH_PIN) { - sc_debug(card->ctx, "P15 Label %s\n", p15card->label); - p15card->label = realloc(p15card->label, - strlen(p15card->label) + strlen(labelPinDomain) + 5); - if (!p15card->label) - return SC_ERROR_MEMORY_FAILURE; - - strcat(p15card->label, " ("); - strcat(p15card->label, labelPinDomain); - strcat(p15card->label, ")"); - - memset(&tokeninfo, 0, sizeof(tokeninfo)); - - tokeninfo.label = p15card->label; - - sc_debug(card->ctx, "Before cosm_update_tokeninfo()"); - rv = cosm_update_tokeninfo(p15card, profile, &tokeninfo); - return rv; - } - - sc_debug(p15card->card->ctx, "object %s; type 0x%X; der length %i; data %p\n", - object->label, object->type, object->der.len, object->data); - rv = cosm_path_to_index (object, &index, &der); - if (rv) { - sc_debug(p15card->card->ctx, "return %i", rv); - return rv; - } - sc_debug(p15card->card->ctx, "der.value %p; der.len %i\n", der.value, der.len); - - rv = cosm_oberthur_new_file(profile, card, object->type, - index, &info_file, &obj_file); - if (rv) { - sc_debug(p15card->card->ctx, "return %i", rv); - return rv; - } - - switch (object->type) { - case SC_PKCS15_TYPE_PRKEY_RSA: - case SC_PKCS15_TYPE_PUBKEY_RSA: - pubkey.algorithm = SC_ALGORITHM_RSA; - - rv = sc_pkcs15_decode_pubkey(card->ctx, &pubkey, der.value, der.len); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - rv = cosm_encode_key_info(card, &pubkey.u.rsa, object->type, &ikey); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - rv = cosm_set_key_info(profile, card, info_file, &ikey, NULL); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - rv = cosm_update_object_list(profile, card, object->type, index); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - /* - * Look for the container that contains corresponding certificate to - * include the key object. - * Create a new container, if there is no corresponding certificate. - */ - rv = cosm_update_container(profile, card, object->type, &ikey.id, index, NULL); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - rv = cosm_set_id (card->ctx, object, ikey.id.value, ikey.id.len); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - cosm_free_key_info(&ikey); - break; - case SC_PKCS15_TYPE_CERT_X509: - rv = cosm_encode_cert_info(card, &der, &icert); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - rv = cosm_set_certificate_info(profile, card, info_file, &icert); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - rv = cosm_update_object_list(profile, card, object->type, index); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - /* - * Look for the container that contains corresponding key to - * include this certificate object. - * Create a new container, if there is no corresponding key. - */ - rv = cosm_update_container(profile, card, object->type, &icert.key.id, index, - &prvkey_id); - if (rv) - break; - - sc_debug(card->ctx, "rv %i; friend 0x%X\n", rv, prvkey_id); - if (prvkey_id) - rv = cosm_update_key_info(profile, card, prvkey_id, &icert); - - rv = cosm_set_id (card->ctx, object, icert.key.id.value, icert.key.id.len); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - cosm_free_cert_info(&icert); - break; - case SC_PKCS15_TYPE_DATA_OBJECT: - rv = cosm_encode_data_info(card, &der, - (sc_pkcs15_data_info_t *)object->data, &idata); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - rv = cosm_set_data_info(profile, card, info_file, &idata); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - rv = cosm_update_object_list(profile, card, object->type, index); - sc_debug(card->ctx, "rv %i\n", rv); - if (rv) - break; - - cosm_free_data_info(&idata); - break; - default: - sc_debug(card->ctx, "Unsupported type %i\n", object->type); - return SC_ERROR_INVALID_ARGUMENTS; - } - - sc_debug(card->ctx, "rv %i\n",rv); - - if (rv > 0) - rv = 0; - - if (info_file) - sc_file_free(info_file); - if (obj_file) - sc_file_free(obj_file); - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - - -static int -cosm_update_df(struct sc_pkcs15_card *p15card, - struct sc_profile *profile, - int op, - struct sc_pkcs15_object *object) -{ - switch(op) { - case SC_AC_OP_ERASE: - return cosm_update_df_delete_object(p15card, profile, object); - case SC_AC_OP_CREATE: - return cosm_update_df_new_object(p15card, profile, object); - default: - return SC_ERROR_NOT_SUPPORTED; - } -} - - -static int -cosm_update_dir (struct sc_pkcs15_card *p15card, - struct sc_profile *profile, struct sc_app_info *info) -{ - sc_debug(p15card->card->ctx, "return 0"); - return 0; -} - - -static int -cosm_update_tokeninfo (struct sc_pkcs15_card *p15card, - struct sc_profile *profile, struct sc_pkcs15_tokeninfo *info) -{ - int rv, sz; - char *buffer = NULL; - struct sc_file *file = NULL; - - if (!p15card || !profile || !info) - return SC_ERROR_INVALID_ARGUMENTS; - - SC_FUNC_CALLED(p15card->card->ctx, 1); - - if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) { - sc_debug(p15card->card->ctx, - "Inconsistent profile: cannot find "COSM_TITLE"-token-info"); - return SC_ERROR_INCONSISTENT_PROFILE; - } - - buffer = malloc(file->size + 1); - if (!buffer) - SC_FUNC_RETURN(p15card->card->ctx, 1, SC_ERROR_MEMORY_FAILURE); - - if (info->label) { - strncpy(buffer, info->label, file->size); - } - else { - snprintf(buffer, file->size, "IDX-SCM"); - } - - sc_debug(p15card->card->ctx, "buffer: '%s'", info->label); - *(buffer + file->size) = '\0'; - - sc_debug(p15card->card->ctx, "buffer '%s'\n", buffer); - sz = strlen(buffer); - if (sz < file->size) - memset(buffer + sz, ' ', file->size - sz); - - memcpy(buffer + file->size - 4, "\0\0\x4\xD", 4); - rv = sc_pkcs15init_update_file(profile, p15card->card, file, buffer, file->size); - - free(buffer); - - SC_FUNC_RETURN(p15card->card->ctx, 1, rv); -} - - -int cosm_write_info (struct sc_card *card, - struct sc_profile *profile, struct sc_pkcs15_object *object) -{ - return SC_SUCCESS; -} - - -int -cosm_change_label(struct sc_pkcs15_card *p15card, struct sc_profile *profile, - struct sc_pkcs15_object *object, - void *value, int len) -{ - struct sc_card *card = p15card->card; - int rv; - - SC_FUNC_CALLED(card->ctx, 1); - sc_debug(card->ctx, "len %i\n", len); - if (len >= SC_PKCS15_MAX_LABEL_SIZE) - return SC_ERROR_INVALID_ARGUMENTS; - - memcpy(object->label, value, len); - object->label[len] = '\0'; -#if 0 - /* TODO */ -#else - rv = 0; -#endif - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - - -int -cosm_change_id(struct sc_pkcs15_card *p15card, struct sc_profile *profile, - struct sc_pkcs15_object *object, struct sc_pkcs15_id *in_id) -{ - struct sc_card *card = p15card->card; - struct sc_pkcs15_id *id; - - SC_FUNC_CALLED(card->ctx, 1); - if (!object || !in_id) - return SC_ERROR_INVALID_ARGUMENTS; - - switch(object->type & SC_PKCS15_TYPE_CLASS_MASK) { - case SC_PKCS15_TYPE_PRKEY: - id = &(((sc_pkcs15_prkey_info_t *) object->data)->id); - break; - case SC_PKCS15_TYPE_PUBKEY: - id = &(((sc_pkcs15_pubkey_info_t *) object->data)->id); - break; - case SC_PKCS15_TYPE_CERT: - id = &(((sc_pkcs15_cert_info_t *) object->data)->id); - break; - default: - return SC_ERROR_NOT_SUPPORTED; - } - - if (id->len != in_id->len || memcmp(id->value, in_id->value, id->len)) { - sc_debug(card->ctx, "obj.id %s; in.id %s\n", - sc_pkcs15_print_id(id), sc_pkcs15_print_id(in_id)); - return SC_ERROR_NOT_SUPPORTED; - } - - SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS); -} - - -int -cosm_change_attrib(struct sc_pkcs15_card *p15card, - struct sc_profile *profile, struct sc_pkcs15_object *object, - int new_attrib_type, void *new_value, int new_len) -{ - struct sc_card *card = p15card->card; - int rv; - - SC_FUNC_CALLED(card->ctx, 1); - sc_debug(card->ctx, "attribute type 0x%X; len %i\n", new_attrib_type, new_len); - if (!p15card || !object || !new_value || new_len < 1) - return SC_ERROR_OBJECT_NOT_FOUND; - - switch(new_attrib_type) { - case P15_ATTR_TYPE_LABEL: - rv = cosm_change_label(p15card, profile, object, new_value, new_len); - break; - case P15_ATTR_TYPE_ID: - if (new_len != sizeof(struct sc_pkcs15_id)) - return SC_ERROR_INVALID_ARGUMENTS; - - rv = cosm_change_id(p15card, profile, object, (struct sc_pkcs15_id *)new_value); - break; - default: - rv = SC_ERROR_NOT_SUPPORTED; - break; - } - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - - -int -cosm_select_id (struct sc_pkcs15_card *p15card, int type, - sc_pkcs15_id_t *id, void *data) -{ - SC_FUNC_CALLED(p15card->card->ctx, 1); -#ifdef ENABLE_OPENSSL - if (!data || !id) - SC_FUNC_RETURN(p15card->card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - - if (type == SC_PKCS15_TYPE_PRKEY) { - struct sc_pkcs15_prkey *key = (struct sc_pkcs15_prkey *)data; - if (key->algorithm == SC_ALGORITHM_RSA) { - struct sc_pkcs15_prkey_rsa *rsa = &key->u.rsa; - - SHA1(rsa->modulus.data, rsa->modulus.len, id->value); - id->len = SHA_DIGEST_LENGTH; - sc_debug(p15card->card->ctx, "private key ID %s\n", sc_pkcs15_print_id(id)); - } - } - else if (type == SC_PKCS15_TYPE_CERT) { - struct sc_pkcs15_der *der = (struct sc_pkcs15_der *)data; - EVP_PKEY *pkey = NULL; - X509 *x = NULL; - BIO *mem = NULL; - BIGNUM *bn = NULL; - unsigned char *buff = NULL; - int rv, bn_size; - - rv = SC_ERROR_INTERNAL; - id->len = 0; - do { - mem = BIO_new_mem_buf(der->value, der->len); - if (!mem) - break; - x = d2i_X509_bio(mem, NULL); - if (!x) - break; - pkey=X509_get_pubkey(x); - if (!pkey || pkey->type != EVP_PKEY_RSA) - break; - bn = pkey->pkey.rsa->n; - bn_size = BN_num_bytes(pkey->pkey.rsa->n); - - buff = OPENSSL_malloc(bn_size); - if (!buff) - break; - if (BN_bn2bin(bn, buff) != bn_size) - break; - if (!SHA1(buff, bn_size, id->value)) - break; - id->len = SHA_DIGEST_LENGTH; - - sc_debug(p15card->card->ctx, "cert ID %s\n", sc_pkcs15_print_id(id)); - rv = SC_SUCCESS; - } while (0); - - if (x) - X509_free(x); - if (mem) - BIO_free(mem); - if (buff) - OPENSSL_free(buff); - - SC_FUNC_RETURN(p15card->card->ctx, 1, rv); - } - else if (type == SC_PKCS15_TYPE_PUBKEY) { - struct sc_pkcs15_pubkey *key = (struct sc_pkcs15_pubkey *)data; - - if (key->algorithm == SC_ALGORITHM_RSA) { - struct sc_pkcs15_pubkey_rsa *rsa = &key->u.rsa; - - SHA1(rsa->modulus.data, rsa->modulus.len, id->value); - id->len = SHA_DIGEST_LENGTH; - sc_debug(p15card->card->ctx, "public key ID %s\n", sc_pkcs15_print_id(id)); - } - } -#endif - SC_FUNC_RETURN(p15card->card->ctx, 1, 0); -} -#endif /* COSM_EXTENDED */ static struct sc_pkcs15init_operations sc_pkcs15init_oberthur_operations = { @@ -1292,18 +703,6 @@ sc_pkcs15init_oberthur_operations = { cosm_new_key, cosm_new_file, cosm_old_generate_key, - -#ifdef COSM_EXTENDED - cosm_delete_object, /* delete_object */ - NULL, /* ext_store_data */ - NULL, /* ext_remove_data */ - cosm_update_df, /* ext_update_df */ - cosm_update_dir, /* ext_update_dir */ - cosm_update_tokeninfo, /* ext_update_tokeninfo */ - cosm_write_info, /* ext_write_info */ - cosm_change_attrib, /* ext_pkcs15init_change_attrib */ - cosm_select_id, /* ext_select_id */ -#endif NULL }; From 36f26b63576c5a8d550e82ec9c7a594743d23d37 Mon Sep 17 00:00:00 2001 From: martin Date: Tue, 10 Nov 2009 10:05:51 +0000 Subject: [PATCH 38/57] Do not duplicate reader name in private structure. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3812 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/reader-pcsc.c | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/src/libopensc/reader-pcsc.c b/src/libopensc/reader-pcsc.c index 5d91cbc0..cbd2db05 100644 --- a/src/libopensc/reader-pcsc.c +++ b/src/libopensc/reader-pcsc.c @@ -70,7 +70,6 @@ struct pcsc_global_private_data { }; struct pcsc_private_data { - char *reader_name; struct pcsc_global_private_data *gpriv; }; @@ -268,7 +267,7 @@ static int refresh_slot_attributes(sc_reader_t *reader, sc_slot_info_t *slot) SC_FUNC_CALLED(reader->ctx, 3); if (pslot->reader_state.szReader == NULL) { - pslot->reader_state.szReader = priv->reader_name; + pslot->reader_state.szReader = reader->name; pslot->reader_state.dwCurrentState = SCARD_STATE_UNAWARE; pslot->reader_state.dwEventState = SCARD_STATE_UNAWARE; } else { @@ -383,7 +382,7 @@ static int pcsc_wait_for_event(sc_reader_t **readers, for (i = 0; i < nslots; i++) { struct pcsc_private_data *priv2 = GET_PRIV_DATA(readers[i]); - rgReaderStates[i].szReader = priv2->reader_name; + rgReaderStates[i].szReader = readers[i]->name; rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE; rgReaderStates[i].dwEventState = SCARD_STATE_UNAWARE; @@ -508,10 +507,6 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot) struct pcsc_private_data *priv = GET_PRIV_DATA(reader); struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot); int r; - u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE]; - size_t rcount; - DWORD i, feature_len, display_ioctl = 0; - PCSC_TLV_STRUCTURE *pcsc_tlv; r = refresh_slot_attributes(reader, slot); if (r) @@ -520,7 +515,7 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot) return SC_ERROR_CARD_NOT_PRESENT; /* Always connect with whatever protocol possible */ - rv = priv->gpriv->SCardConnect(priv->gpriv->pcsc_ctx, priv->reader_name, + rv = priv->gpriv->SCardConnect(priv->gpriv->pcsc_ctx, reader->name, priv->gpriv->connect_exclusive ? SCARD_SHARE_EXCLUSIVE : SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY, &card_handle, &active_proto); if (rv != SCARD_S_SUCCESS) { @@ -627,7 +622,6 @@ static int pcsc_release(sc_reader_t *reader) { struct pcsc_private_data *priv = GET_PRIV_DATA(reader); - free(priv->reader_name); free(priv); if (reader->slot[0].drv_data != NULL) { free(reader->slot[0].drv_data); @@ -902,10 +896,6 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) goto err1; } priv->gpriv = gpriv; - if ((priv->reader_name = strdup(reader_name)) == NULL) { - ret = SC_ERROR_OUT_OF_MEMORY; - goto err1; - } slot = &reader->slot[0]; memset(slot, 0, sizeof(*slot)); slot->drv_data = pslot; @@ -919,11 +909,11 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) if (gpriv->SCardControl != NULL) { sc_debug(ctx, "Requesting reader features ... "); #ifdef __APPLE__ /* 10.5.7 does not support 0 as protocol identifier */ - rv = gpriv->SCardConnect(gpriv->pcsc_ctx, priv->reader_name, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_ANY, &card_handle, &active_proto); + rv = gpriv->SCardConnect(gpriv->pcsc_ctx, reader->name, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_ANY, &card_handle, &active_proto); #else - rv = gpriv->SCardConnect(gpriv->pcsc_ctx, priv->reader_name, SCARD_SHARE_DIRECT, 0, &card_handle, &active_proto); + rv = gpriv->SCardConnect(gpriv->pcsc_ctx, reader->name, SCARD_SHARE_DIRECT, 0, &card_handle, &active_proto); if (rv == SCARD_E_SHARING_VIOLATION) /* Assume that there is a card in the reader in shared mode */ - rv = gpriv->SCardConnect(gpriv->pcsc_ctx, priv->reader_name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY, &card_handle, &active_proto); + rv = gpriv->SCardConnect(gpriv->pcsc_ctx, reader->name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY, &card_handle, &active_proto); #endif if (rv == SCARD_S_SUCCESS) { rv = gpriv->SCardControl(card_handle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, feature_buf, sizeof(feature_buf), &feature_len); @@ -1011,8 +1001,6 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) err1: if (priv != NULL) { - if (priv->reader_name) - free(priv->reader_name); free(priv); } if (reader != NULL) { From 3ea5bb7987601f0cbf42aeb30176af7d318b0ac0 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 09:45:21 +0000 Subject: [PATCH 39/57] Merge [3804:3822/trunk] git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3824 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-oberthur.c | 584 ++++++++++++++----------------- src/libopensc/card-rutoken.c | 9 +- src/libopensc/libopensc.exports | 2 + src/libopensc/opensc.h | 6 + src/libopensc/pkcs15-pubkey.c | 170 ++++++++- src/libopensc/pkcs15-syn.c | 2 +- src/libopensc/pkcs15.c | 4 +- src/libopensc/pkcs15.h | 43 ++- src/pkcs11/framework-pkcs15.c | 23 +- src/pkcs15init/oberthur.profile | 5 +- src/pkcs15init/pkcs15-init.h | 4 + src/pkcs15init/pkcs15-lib.c | 147 +++++++- src/pkcs15init/pkcs15-oberthur.c | 388 +++++++++++++------- src/pkcs15init/pkcs15.profile | 8 +- src/pkcs15init/profile.c | 19 +- src/pkcs15init/profile.h | 3 + src/tools/pkcs15-tool.c | 32 +- 17 files changed, 925 insertions(+), 524 deletions(-) diff --git a/src/libopensc/card-oberthur.c b/src/libopensc/card-oberthur.c index fab3a3b1..be5da48d 100644 --- a/src/libopensc/card-oberthur.c +++ b/src/libopensc/card-oberthur.c @@ -3,7 +3,7 @@ * CosmopolIC v5; * * Copyright (C) 2001, 2002 Juha Yrjölä - * Copyright (C) 2009 Viktor Tarasov , + * Copyright (C) 2009 Viktor Tarasov , * OpenTrust * * This library is free software; you can redistribute it and/or @@ -36,6 +36,12 @@ #include #include +/* #define OBERTHUR_VERIFY_SOPIN_TRY_LOCAL */ + +#define OBERTHUR_PIN_LOCAL 0x80 +#define OBERTHUR_PIN_REFERENCE_USER 0x01 +#define OBERTHUR_PIN_REFERENCE_SO 0x04 + /* keep OpenSSL 0.9.6 users happy ;-) */ #if OPENSSL_VERSION_NUMBER < 0x00907000L #define DES_cblock des_cblock @@ -63,18 +69,16 @@ struct auth_senv { int key_file_id; size_t key_size; }; -typedef struct auth_senv auth_senv_t; struct auth_private_data { unsigned char aid[SC_MAX_AID_SIZE]; int aid_len; struct sc_pin_cmd_pin pin_info; - auth_senv_t senv; + struct auth_senv senv; long int sn; }; -typedef struct auth_private_data auth_private_data_t; struct auth_update_component_info { enum SC_CARDCTL_OBERTHUR_KEY_TYPE type; @@ -82,11 +86,10 @@ struct auth_update_component_info { unsigned char *data; unsigned int len; }; -typedef struct auth_update_component_info auth_update_component_info_t; static const unsigned char *aidAuthentIC_V5 = - (const u8 *)"\xA0\x00\x00\x00\x77\x01\x03\x03\x00\x00\x00\xF1\x00\x00\x00\x02"; + (const unsigned char *)"\xA0\x00\x00\x00\x77\x01\x03\x03\x00\x00\x00\xF1\x00\x00\x00\x02"; static const int lenAidAuthentIC_V5 = 16; static const char *nameAidAuthentIC_V5 = "AuthentIC v5"; @@ -102,7 +105,7 @@ static const char *nameAidAuthentIC_V5 = "AuthentIC v5"; static unsigned char rsa_der[PUBKEY_2048_ASN1_SIZE]; static int rsa_der_len = 0; -static sc_file_t *auth_current_ef = NULL, *auth_current_df = NULL; +static struct sc_file *auth_current_ef = NULL, *auth_current_df = NULL; static struct sc_card_operations auth_ops; static struct sc_card_operations *iso_ops; static struct sc_card_driver auth_drv = { @@ -112,22 +115,24 @@ static struct sc_card_driver auth_drv = { NULL, 0, NULL }; -static int auth_get_pin_reference (sc_card_t *card, +static int auth_get_pin_reference (struct sc_card *card, int type, int reference, int cmd, int *out_ref); -static int auth_read_component(sc_card_t *card, +static int auth_read_component(struct sc_card *card, enum SC_CARDCTL_OBERTHUR_KEY_TYPE type, int num, unsigned char *out, size_t outlen); -static int auth_verify(sc_card_t *card, unsigned int type, - int ref, const u8 *data, size_t data_len, int *tries_left); -static int auth_create_reference_data (sc_card_t *card, +static int auth_is_verified(struct sc_card *card, int pin_reference, + int *tries_left); +static int auth_verify(struct sc_card *card, unsigned int type, + struct sc_pin_cmd_data *data, int *tries_left); +static int auth_create_reference_data (struct sc_card *card, struct sc_cardctl_oberthur_createpin_info *args); -static int auth_get_serialnr(sc_card_t *card, sc_serial_number_t *serial); -static int auth_select_file(sc_card_t *card, const sc_path_t *in_path, - sc_file_t **file_out); +static int auth_get_serialnr(struct sc_card *card, struct sc_serial_number *serial); +static int auth_select_file(struct sc_card *card, const struct sc_path *in_path, + struct sc_file **file_out); static int -auth_finish(sc_card_t *card) +auth_finish(struct sc_card *card) { free(card->drv_data); return SC_SUCCESS; @@ -135,20 +140,19 @@ auth_finish(sc_card_t *card) static int -auth_select_aid(sc_card_t *card) +auth_select_aid(struct sc_card *card) { - sc_apdu_t apdu; + struct sc_apdu apdu; unsigned char apdu_resp[SC_MAX_APDU_BUFFER_SIZE]; struct auth_private_data *data = (struct auth_private_data *) card->drv_data; int rv, ii; unsigned char cm[7] = {0xA0,0x00,0x00,0x00,0x03,0x00,0x00}; - sc_path_t tmp_path; + struct sc_path tmp_path; /* Select Card Manager (to deselect previously selected application) */ sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C); apdu.lc = sizeof(cm); /* apdu.le = sizeof(cm)+4; */ - apdu.le = 0; apdu.data = cm; apdu.datalen = sizeof(cm); apdu.resplen = sizeof(apdu_resp); @@ -198,8 +202,9 @@ auth_select_aid(sc_card_t *card) SC_FUNC_RETURN(card->ctx, 1, rv); } + static int -auth_match_card(sc_card_t *card) +auth_match_card(struct sc_card *card) { if (_sc_match_atr(card, oberthur_atrs, &card->type) < 0) return 0; @@ -207,19 +212,18 @@ auth_match_card(sc_card_t *card) return 1; } + static int -auth_init(sc_card_t *card) +auth_init(struct sc_card *card) { - int rv = 0; - unsigned long flags; struct auth_private_data *data; - sc_path_t path; + struct sc_path path; + unsigned long flags; + int rv = 0; - data = (struct auth_private_data *) malloc(sizeof(struct auth_private_data)); + data = (struct auth_private_data *) calloc(1, sizeof(struct auth_private_data)); if (!data) SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_OUT_OF_MEMORY); - else - memset(data, 0, sizeof(struct auth_private_data)); card->cla = 0x00; card->drv_data = data; @@ -262,8 +266,8 @@ auth_init(sc_card_t *card) static void -add_acl_entry(sc_card_t *card, sc_file_t *file, unsigned int op, - u8 acl_byte) +add_acl_entry(struct sc_card *card, struct sc_file *file, unsigned int op, + unsigned char acl_byte) { if ((acl_byte & 0xE0) == 0x60) { sc_debug(card->ctx, "called; op 0x%X; SC_AC_PRO; ref 0x%X\n", op, acl_byte); @@ -293,8 +297,7 @@ add_acl_entry(sc_card_t *card, sc_file_t *file, unsigned int op, static int -tlv_get(const unsigned char *msg, int len, - unsigned char tag, +tlv_get(const unsigned char *msg, int len, unsigned char tag, unsigned char *ret, int *ret_len) { int cur = 0; @@ -409,6 +412,9 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, add_acl_entry(card, file, SC_AC_OP_CRYPTO, attr[1]); add_acl_entry(card, file, SC_AC_OP_LIST_FILES, attr[2]); add_acl_entry(card, file, SC_AC_OP_DELETE, attr[3]); + add_acl_entry(card, file, SC_AC_OP_PIN_DEFINE, attr[4]); + add_acl_entry(card, file, SC_AC_OP_PIN_CHANGE, attr[5]); + add_acl_entry(card, file, SC_AC_OP_PIN_RESET, attr[6]); } else if (file->type == SC_FILE_TYPE_INTERNAL_EF) { /* EF */ switch (file->ef_structure) { @@ -451,18 +457,18 @@ auth_process_fci(struct sc_card *card, struct sc_file *file, static int -auth_select_file(sc_card_t *card, const sc_path_t *in_path, - sc_file_t **file_out) +auth_select_file(struct sc_card *card, const struct sc_path *in_path, + struct sc_file **file_out) { - int rv; + struct sc_path path; + struct sc_file *tmp_file = NULL; size_t offs, ii; - sc_path_t path; - sc_file_t *tmp_file = NULL; + int rv; SC_FUNC_CALLED(card->ctx, 1); assert(card != NULL && in_path != NULL); - memcpy(&path, in_path, sizeof(sc_path_t)); + memcpy(&path, in_path, sizeof(struct sc_path)); sc_debug(card->ctx, "in_path; type=%d, path=%s, out %p\n", in_path->type, sc_print_path(in_path), file_out); @@ -481,7 +487,7 @@ auth_select_file(sc_card_t *card, const sc_path_t *in_path, SC_TEST_RET(card->ctx, rv, "select file failed"); if (path.type == SC_PATH_TYPE_PARENT) { - memcpy(&tmp_file->path, &auth_current_df->path, sizeof(sc_path_t)); + memcpy(&tmp_file->path, &auth_current_df->path, sizeof(struct sc_path)); if (tmp_file->path.len > 2) tmp_file->path.len -= 2; @@ -529,9 +535,9 @@ auth_select_file(sc_card_t *card, const sc_path_t *in_path, sc_debug(card->ctx, "deep %i\n", deep); for (ii=0; iipath, sizeof(sc_path_t)); + memcpy(&tmp_path, &auth_current_df->path, sizeof(struct sc_path)); tmp_path.type = SC_PATH_TYPE_PARENT; rv = auth_select_file (card, &tmp_path, file_out); @@ -540,7 +546,7 @@ auth_select_file(sc_card_t *card, const sc_path_t *in_path, } if (path.len - offs > 0) { - sc_path_t tmp_path; + struct sc_path tmp_path; tmp_path.type = SC_PATH_TYPE_FILE_ID; tmp_path.len = 2; @@ -567,10 +573,10 @@ auth_select_file(sc_card_t *card, const sc_path_t *in_path, static int -auth_list_files(sc_card_t *card, u8 *buf, size_t buflen) +auth_list_files(struct sc_card *card, unsigned char *buf, size_t buflen) { - sc_apdu_t apdu; - u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; + struct sc_apdu apdu; + unsigned char rbuf[SC_MAX_APDU_BUFFER_SIZE]; int rv; SC_FUNC_CALLED(card->ctx, 1); @@ -597,11 +603,11 @@ auth_list_files(sc_card_t *card, u8 *buf, size_t buflen) static int -auth_delete_file(sc_card_t *card, const sc_path_t *path) +auth_delete_file(struct sc_card *card, const struct sc_path *path) { + struct sc_apdu apdu; + unsigned char sbuf[2]; int rv; - u8 sbuf[2]; - sc_apdu_t apdu; SC_FUNC_CALLED(card->ctx, 1); if (card->ctx->debug >= 1) { @@ -620,7 +626,7 @@ auth_delete_file(sc_card_t *card, const sc_path_t *path) } if (path->len > 2) { - sc_path_t parent = *path; + struct sc_path parent = *path; parent.len -= 2; parent.type = SC_PATH_TYPE_PATH; @@ -643,10 +649,10 @@ auth_delete_file(sc_card_t *card, const sc_path_t *path) rv = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); if (apdu.sw1==0x6A && apdu.sw2==0x82) { - /* Clean the DF contents.*/ - sc_path_t tmp_path; - u8 lbuf[SC_MAX_APDU_BUFFER_SIZE]; + /* Clean up tDF contents.*/ + struct sc_path tmp_path; int ii, len; + unsigned char lbuf[SC_MAX_APDU_BUFFER_SIZE]; tmp_path.type = SC_PATH_TYPE_FILE_ID; memcpy(tmp_path.value, sbuf, 2); @@ -658,7 +664,7 @@ auth_delete_file(sc_card_t *card, const sc_path_t *path) SC_TEST_RET(card->ctx, len, "list DF failed"); for (ii=0; iictx, 1); @@ -833,9 +839,9 @@ encode_file_structure_V5(sc_card_t *card, const sc_file_t *file, ops[1] = SC_AC_OP_CRYPTO; ops[2] = SC_AC_OP_LIST_FILES; ops[3] = SC_AC_OP_DELETE; - ops[4] = SC_AC_OP_LIST_FILES; /* SC_AC_OP_SET_REFERENCE */ - ops[5] = SC_AC_OP_LIST_FILES; /* SC_AC_OP_CHANGE_REFERENCE */ - ops[6] = SC_AC_OP_LIST_FILES; /* SC_AC_OP_RESET_COUNTER */ + ops[4] = SC_AC_OP_PIN_DEFINE; + ops[5] = SC_AC_OP_PIN_CHANGE; + ops[6] = SC_AC_OP_PIN_RESET; } else if (file->type == SC_FILE_TYPE_WORKING_EF) { if (file->ef_structure == SC_FILE_EF_TRANSPARENT) { @@ -877,7 +883,7 @@ encode_file_structure_V5(sc_card_t *card, const sc_file_t *file, } for (ii = 0; ii < sizeof(ops); ii++) { - const sc_acl_entry_t *entry; + const struct sc_acl_entry *entry; p[16+ii] = 0xFF; if (ops[ii]==0xFF) @@ -895,13 +901,13 @@ encode_file_structure_V5(sc_card_t *card, const sc_file_t *file, static int -auth_create_file(sc_card_t *card, sc_file_t *file) +auth_create_file(struct sc_card *card, struct sc_file *file) { - u8 sbuf[0x18]; - size_t sendlen = sizeof(sbuf); + struct sc_apdu apdu; + struct sc_path path; int rv, rec_nr; - sc_apdu_t apdu; - sc_path_t path; + unsigned char sbuf[0x18]; + size_t sendlen = sizeof(sbuf); char pbuf[SC_MAX_PATH_STRING_SIZE]; SC_FUNC_CALLED(card->ctx, 1); @@ -955,8 +961,8 @@ auth_create_file(sc_card_t *card, sc_file_t *file) /* select created DF. */ if (file->type == SC_FILE_TYPE_DF) { - sc_path_t tmp_path; - sc_file_t *df_file = NULL; + struct sc_path tmp_path; + struct sc_file *df_file = NULL; tmp_path.type = SC_PATH_TYPE_FILE_ID; tmp_path.value[0] = file->id >> 8; @@ -974,30 +980,30 @@ auth_create_file(sc_card_t *card, sc_file_t *file) SC_FUNC_RETURN(card->ctx, 1, rv); } + static int -auth_set_security_env(sc_card_t *card, - const sc_security_env_t *env, int se_num) +auth_set_security_env(struct sc_card *card, + const struct sc_security_env *env, int se_num) { - auth_senv_t *auth_senv = &((struct auth_private_data *) card->drv_data)->senv; + struct auth_senv *auth_senv = &((struct auth_private_data *) card->drv_data)->senv; + struct sc_apdu apdu; long unsigned pads = env->algorithm_flags & SC_ALGORITHM_RSA_PADS; - long unsigned supported_pads = - SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ISO9796; - sc_apdu_t apdu; - u8 rsa_sbuf[3] = { + long unsigned supported_pads = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_PAD_ISO9796; + int rv; + unsigned char rsa_sbuf[3] = { 0x80, 0x01, 0xFF }; - u8 des_sbuf[13] = { + unsigned char des_sbuf[13] = { 0x80, 0x01, 0x01, 0x87, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - int rv; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "op %i; path %s; key_ref 0x%X; algos 0x%X; flags 0x%X\n", env->operation, sc_print_path(&env->file_ref), env->key_ref[0], env->algorithm_flags, env->flags); - memset(auth_senv, 0, sizeof(auth_senv_t)); + memset(auth_senv, 0, sizeof(struct auth_senv)); if (!(env->flags & SC_SEC_ENV_FILE_REF_PRESENT)) SC_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "Key file is not selected."); @@ -1069,17 +1075,17 @@ auth_set_security_env(sc_card_t *card, static int -auth_restore_security_env(sc_card_t *card, int se_num) +auth_restore_security_env(struct sc_card *card, int se_num) { return SC_SUCCESS; } static int -auth_compute_signature(sc_card_t *card, - const u8 *in, size_t ilen, u8 * out, size_t olen) +auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ilen, + unsigned char * out, size_t olen) { - sc_apdu_t apdu; + struct sc_apdu apdu; unsigned char resp[SC_MAX_APDU_BUFFER_SIZE]; int rv; @@ -1119,11 +1125,11 @@ auth_compute_signature(sc_card_t *card, static int -auth_decipher(sc_card_t *card, const u8 *in, size_t inlen, - u8 *out, size_t outlen) +auth_decipher(struct sc_card *card, const unsigned char *in, size_t inlen, + unsigned char *out, size_t outlen) { - sc_apdu_t apdu; - u8 resp[SC_MAX_APDU_BUFFER_SIZE]; + struct sc_apdu apdu; + unsigned char resp[SC_MAX_APDU_BUFFER_SIZE]; int rv, _inlen = inlen; SC_FUNC_CALLED(card->ctx, 1); @@ -1199,16 +1205,14 @@ done: /* Return the default AAK for this type of card */ static int -auth_get_default_key(sc_card_t *card, struct sc_cardctl_default_key *data) +auth_get_default_key(struct sc_card *card, struct sc_cardctl_default_key *data) { - int rv = SC_ERROR_NO_DEFAULT_KEY; - - SC_FUNC_RETURN(card->ctx, 1, rv); + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NO_DEFAULT_KEY); } static int -auth_encode_exponent(unsigned long exponent, u8 *buff, size_t buff_len) +auth_encode_exponent(unsigned long exponent, unsigned char *buff, size_t buff_len) { int shift; size_t ii; @@ -1228,12 +1232,12 @@ auth_encode_exponent(unsigned long exponent, u8 *buff, size_t buff_len) /* Generate key on-card */ static int -auth_generate_key(sc_card_t *card, int use_sm, +auth_generate_key(struct sc_card *card, int use_sm, struct sc_cardctl_oberthur_genkey_info *data) { - sc_apdu_t apdu; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - sc_path_t tmp_path; + struct sc_apdu apdu; + unsigned char sbuf[SC_MAX_APDU_BUFFER_SIZE]; + struct sc_path tmp_path; int rv = 0; SC_FUNC_CALLED(card->ctx, 1); @@ -1255,9 +1259,10 @@ auth_generate_key(sc_card_t *card, int use_sm, } sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x46, 0x00, 0x00); - if (!(apdu.resp = (u8 *) malloc(data->key_bits/8+8))) { + apdu.resp = (unsigned char *) calloc(1, data->key_bits/8+8); + if (!apdu.resp) SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_OUT_OF_MEMORY); - } + apdu.resplen = data->key_bits/8+8; apdu.lc = rv + 4; apdu.le = data->key_bits/8; @@ -1298,11 +1303,11 @@ auth_generate_key(sc_card_t *card, int use_sm, static int -auth_update_component(sc_card_t *card, struct auth_update_component_info *args) +auth_update_component(struct sc_card *card, struct auth_update_component_info *args) { - sc_apdu_t apdu; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE + 0x10]; - u8 ins, p1, p2; + struct sc_apdu apdu; + unsigned char sbuf[SC_MAX_APDU_BUFFER_SIZE + 0x10]; + unsigned char ins, p1, p2; int rv, len; SC_FUNC_CALLED(card->ctx, 1); @@ -1386,7 +1391,7 @@ auth_update_component(sc_card_t *card, struct auth_update_component_info *args) static int -auth_update_key(sc_card_t *card, struct sc_cardctl_oberthur_updatekey_info *info) +auth_update_key(struct sc_card *card, struct sc_cardctl_oberthur_updatekey_info *info) { int rv, ii; @@ -1397,7 +1402,7 @@ auth_update_key(sc_card_t *card, struct sc_cardctl_oberthur_updatekey_info *info if (info->type == SC_CARDCTL_OBERTHUR_KEY_RSA_CRT) { struct sc_pkcs15_prkey_rsa *rsa = (struct sc_pkcs15_prkey_rsa *)info->data; - struct sc_pkcs15_bignum bn[5]; + struct sc_pkcs15_bignum bn[5]; sc_debug(card->ctx, "Import RSA CRT"); bn[0] = rsa->p; @@ -1430,7 +1435,7 @@ auth_update_key(sc_card_t *card, struct sc_cardctl_oberthur_updatekey_info *info static int -auth_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) +auth_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) { switch (cmd) { case SC_CARDCTL_GET_DEFAULT_KEY: @@ -1446,7 +1451,7 @@ auth_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) return auth_create_reference_data(card, (struct sc_cardctl_oberthur_createpin_info *) ptr); case SC_CARDCTL_GET_SERIALNR: - return auth_get_serialnr(card, (sc_serial_number_t *)ptr); + return auth_get_serialnr(card, (struct sc_serial_number *)ptr); case SC_CARDCTL_LIFECYCLE_GET: case SC_CARDCTL_LIFECYCLE_SET: return SC_ERROR_NOT_SUPPORTED; @@ -1457,11 +1462,11 @@ auth_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr) static int -auth_read_component(sc_card_t *card, enum SC_CARDCTL_OBERTHUR_KEY_TYPE type, +auth_read_component(struct sc_card *card, enum SC_CARDCTL_OBERTHUR_KEY_TYPE type, int num, unsigned char *out, size_t outlen) { + struct sc_apdu apdu; int rv; - sc_apdu_t apdu; unsigned char resp[SC_MAX_APDU_BUFFER_SIZE]; SC_FUNC_CALLED(card->ctx, 1); @@ -1489,8 +1494,8 @@ auth_read_component(sc_card_t *card, enum SC_CARDCTL_OBERTHUR_KEY_TYPE type, } -static int auth_get_pin_reference (sc_card_t *card, - int type, int reference, int cmd, int *out_ref) +static int +auth_get_pin_reference (struct sc_card *card, int type, int reference, int cmd, int *out_ref) { struct auth_private_data *prv; @@ -1505,7 +1510,7 @@ static int auth_get_pin_reference (sc_card_t *card, SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_PIN_REFERENCE); *out_ref = reference; - if (reference == 1 || reference == 2) + if (reference == 1 || reference == 4) if (cmd == SC_PIN_CMD_VERIFY) *out_ref |= 0x80; break; @@ -1519,10 +1524,10 @@ static int auth_get_pin_reference (sc_card_t *card, static void -auth_init_pin_info(sc_card_t *card, struct sc_pin_cmd_pin *pin, +auth_init_pin_info(struct sc_card *card, struct sc_pin_cmd_pin *pin, unsigned int type) { - pin->offset = 0; + pin->offset = 0; pin->pad_char = 0xFF; pin->encoding = SC_PIN_ENCODING_ASCII; @@ -1538,211 +1543,154 @@ auth_init_pin_info(sc_card_t *card, struct sc_pin_cmd_pin *pin, static int -auth_verify(sc_card_t *card, unsigned int type, - int ref, const u8 *data, size_t data_len, int *tries_left) +auth_verify(struct sc_card *card, unsigned int type, + struct sc_pin_cmd_data *data, int *tries_left) { - sc_apdu_t apdu; - int rv, pin_ref; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - struct sc_pin_cmd_pin pinfo; + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); + int rv; SC_FUNC_CALLED(card->ctx, 1); - sc_debug(card->ctx,"type %i; ref %i, data_len %i\n", type, ref, data_len); - if (ref == 3) { - ref = 1; - rv = auth_get_pin_reference (card, type, ref, SC_PIN_CMD_VERIFY, &pin_ref); - SC_TEST_RET(card->ctx, rv, "Get PIN reference failed"); + if (type != SC_AC_CHV) + SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "PIN type other then SC_AC_CHV is not supported"); - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, pin_ref); - apdu.lc = 0x0; - apdu.le = 0x0; - apdu.resplen = 0; - apdu.resp = NULL; - apdu.p2 = pin_ref; - rv = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); - - if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) { - ref = 2; - rv = auth_get_pin_reference (card, type, ref, SC_PIN_CMD_VERIFY, &pin_ref); - if (rv) - SC_FUNC_RETURN(card->ctx, 1, rv); - - apdu.p2 = pin_ref; - rv = sc_transmit_apdu(card, &apdu); - SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); - } - - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00 ) { - if (data && data_len > 1 && *data!=ref && !isalnum(*data)) { - rv = auth_verify(card, type, *data, - data+1, data_len - 1, tries_left); - } - } - + data->flags |= SC_PIN_CMD_NEED_PADDING; + + auth_init_pin_info(card, &data->pin1, AUTH_PIN); + + /* User PIN is always local. */ + if (data->pin_reference == OBERTHUR_PIN_REFERENCE_USER) + data->pin_reference |= OBERTHUR_PIN_LOCAL; + +#ifdef OBERTHUR_VERIFY_SOPIN_TRY_LOCAL + /* SOPIN can be local -- firstly try to verify the local one. */ + if (data->pin_reference == OBERTHUR_PIN_REFERENCE_SO) + data->pin_reference |= OBERTHUR_PIN_LOCAL; +#endif + + rv = auth_is_verified(card, data->pin_reference, tries_left); + sc_debug(card->ctx, "auth_is_verified returned rv %i\n", rv); + +#ifdef OBERTHUR_VERIFY_SOPIN_TRY_LOCAL + if (rv == SC_ERROR_DATA_OBJECT_NOT_FOUND + && data->pin_reference == OBERTHUR_PIN_REFERENCE_SO | OBERTHUR_PIN_LOCAL) { + /* Local SOPIN is not defined -- try to verify the global one. */ + data->pin_reference &= ~OBERTHUR_PIN_LOCAL; + rv = auth_is_verified(card, data->pin_reference, tries_left); + } +#endif + + /* Return if only PIN status has been asked. */ + if (data->pin1.data && !data->pin1.len) SC_FUNC_RETURN(card->ctx, 1, rv); - } - rv = auth_get_pin_reference (card, type, ref, SC_PIN_CMD_VERIFY, &pin_ref); - SC_TEST_RET(card->ctx, rv, "Get PIN reference failed"); - - sc_debug(card->ctx, " pin_ref %X\n", pin_ref); + /* Return SUCCESS without verifying if + * PIN has been already verified and PIN pad has to be used. */ + if (!rv && !data->pin1.data && !data->pin1.len) + SC_FUNC_RETURN(card->ctx, 1, rv); - auth_init_pin_info(card, &pinfo, AUTH_PIN); - if (data_len > pinfo.pad_length) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); + rv = iso_drv->ops->pin_cmd(card, data, tries_left); + SC_TEST_RET(card->ctx, rv, "PIN CMD 'VERIFY' failed"); - if (data_len) { - memset(sbuf, pinfo.pad_char, pinfo.pad_length); - memcpy(sbuf, data, data_len); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0, pin_ref); - apdu.data = sbuf; - apdu.datalen = pinfo.pad_length; - apdu.lc = pinfo.pad_length; - } - else { - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0, pin_ref); - apdu.lc = 0x0; - apdu.le = 0x0; - apdu.resplen = 0; - apdu.resp = NULL; - } - - rv = sc_transmit_apdu(card, &apdu); - sc_mem_clear(sbuf, sizeof(sbuf)); - SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); - - if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) - *tries_left = apdu.sw2 & 0x0F; - - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_FUNC_RETURN(card->ctx, 1, rv); } -static int -auth_change_reference_data (sc_card_t *card, unsigned int type, - int ref, const u8 *old, size_t oldlen, - const u8 *_new, size_t newlen, int *tries_left) +static int +auth_is_verified(struct sc_card *card, int pin_reference, int *tries_left) { - sc_apdu_t apdu; - int rv, pin_ref; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - struct sc_pin_cmd_pin pinfo; - - SC_FUNC_CALLED(card->ctx, 1); - rv = auth_get_pin_reference (card, type, ref, SC_PIN_CMD_CHANGE, &pin_ref); - SC_TEST_RET(card->ctx, rv, "Failed to get PIN reference"); - - sc_debug(card->ctx, " pin ref %X\n", pin_ref); - - auth_init_pin_info(card, &pinfo, AUTH_PIN); - - if (oldlen > pinfo.pad_length || newlen > pinfo.pad_length) - SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid PIN length"); - - memset(sbuf, pinfo.pad_char, pinfo.pad_length * 2); - memcpy(sbuf, old, oldlen); - memcpy(sbuf + pinfo.pad_length, _new, newlen); - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0, pin_ref); - apdu.data = sbuf; - apdu.datalen = pinfo.pad_length * 2; - apdu.lc = pinfo.pad_length * 2; + struct sc_apdu apdu; + int rv; + + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0, pin_reference); rv = sc_transmit_apdu(card, &apdu); - sc_mem_clear(sbuf, sizeof(sbuf)); SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); - if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) + if (tries_left && apdu.sw1 == 0x63 && (apdu.sw2 & 0xF0) == 0xC0) *tries_left = apdu.sw2 & 0x0F; - rv = sc_check_sw(card, apdu.sw1, apdu.sw2); - - SC_FUNC_RETURN(card->ctx, 1, rv); -} - - -static int -auth_reset_retry_counter(sc_card_t *card, unsigned int type, - int ref, const u8 *puk, size_t puklen, - const u8 *pin, size_t pinlen) -{ - sc_apdu_t apdu; - int rv, pin_ref; - size_t len; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - struct sc_pin_cmd_pin pin_info, puk_info; - - SC_FUNC_CALLED(card->ctx, 1); - rv = auth_get_pin_reference (card, type, ref, SC_PIN_CMD_CHANGE, &pin_ref); - SC_TEST_RET(card->ctx, rv, "Failed to get PIN reference"); - - sc_debug(card->ctx, "pin_ref 0x%X\n", pin_ref); - sc_debug(card->ctx, "current path ; type=%d, path=%s\n", - auth_current_df->path.type, sc_print_path(&auth_current_df->path)); - - auth_init_pin_info(card, &puk_info, AUTH_PUK); - auth_init_pin_info(card, &pin_info, AUTH_PIN); - - if (puklen > puk_info.pad_length || pinlen > pin_info.pad_length) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - - memset(sbuf, puk_info.pad_char, puk_info.pad_length); - memcpy(sbuf, puk, puklen); - len = puk_info.pad_length; - if (pin && pinlen) { - memset(sbuf + len, pin_info.pad_char, pin_info.pad_length); - memcpy(sbuf + len, pin, pinlen); - len += pin_info.pad_length; + /* Replace 'no tries left' with 'auth method blocked' */ + if (apdu.sw1 == 0x63 && apdu.sw2 == 0xC0) { + apdu.sw1 = 0x69; + apdu.sw2 = 0x83; } - - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2C, - len == puk_info.pad_length ? 1 : 0, pin_ref); - apdu.data = sbuf; - apdu.datalen = len; - apdu.lc = len; - - rv = sc_transmit_apdu(card, &apdu); - sc_mem_clear(sbuf, sizeof(sbuf)); - SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); rv = sc_check_sw(card, apdu.sw1, apdu.sw2); + + return rv; +} + + +static int +auth_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left) +{ + struct sc_card_driver *iso_drv = sc_get_iso7816_driver(); + struct auth_private_data *prv_data = (struct auth_private_data *) card->drv_data; + struct sc_apdu apdu; + int rv, _tries_left = 0; + + SC_FUNC_CALLED(card->ctx, 1); + if (data->pin_type != SC_AC_CHV) + SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "auth_pin_cmd() unsupported PIN type"); + + sc_debug(card->ctx, "PIN:%i; lengths %i/%i\n", data->pin_reference, data->pin1.len, data->pin2.len); + switch (data->cmd) { + case SC_PIN_CMD_VERIFY: + rv = auth_verify(card, SC_AC_CHV, data, tries_left); + SC_TEST_RET(card->ctx, rv, "CMD 'PIN VERIFY' failed"); + + break; + case SC_PIN_CMD_CHANGE: + data->flags |= SC_PIN_CMD_NEED_PADDING; + data->apdu = NULL; + + auth_init_pin_info(card, &data->pin1, AUTH_PIN); + auth_init_pin_info(card, &data->pin2, AUTH_PIN); + + rv = iso_drv->ops->pin_cmd(card, data, tries_left); + SC_TEST_RET(card->ctx, rv, "CMD 'PIN CHANGE' failed"); + + break; + case SC_PIN_CMD_UNBLOCK: + data->flags |= SC_PIN_CMD_NEED_PADDING; + data->apdu = NULL; + + auth_init_pin_info(card, &data->pin1, AUTH_PUK); + auth_init_pin_info(card, &data->pin2, AUTH_PIN); + + rv = iso_drv->ops->pin_cmd(card, data, tries_left); + SC_TEST_RET(card->ctx, rv, "CMD 'PIN UNBLOCK' failed"); + + break; + default: + SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported PIN operation"); + } + SC_FUNC_RETURN(card->ctx, 1, rv); } static int -auth_create_reference_data (sc_card_t *card, +auth_create_reference_data (struct sc_card *card, struct sc_cardctl_oberthur_createpin_info *args) { - sc_apdu_t apdu; - int rv, pin_ref, len; - u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; + struct sc_apdu apdu; struct sc_pin_cmd_pin pin_info, puk_info; + int rv, len; + unsigned char sbuf[SC_MAX_APDU_BUFFER_SIZE]; SC_FUNC_CALLED(card->ctx, 1); + sc_debug(card->ctx, "PIN reference %i\n", args->ref); + + if (args->type != SC_AC_CHV) + SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Unsupported PIN type"); if (args->pin_tries < 1 || !args->pin || !args->pin_len) SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Invalid PIN options"); - - if (args->type == SC_AC_CHV) { - if (args->ref == 1) - pin_ref = 0x01; - else if (args->ref == 2) - pin_ref = 0x02; - else - SC_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid PIN reference"); - } - else { - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); - } - - sc_debug(card->ctx, "pin ref %X\n", pin_ref); + + if (args->ref != OBERTHUR_PIN_REFERENCE_USER && args->ref != OBERTHUR_PIN_REFERENCE_SO) + SC_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid PIN reference"); auth_init_pin_info(card, &puk_info, AUTH_PUK); auth_init_pin_info(card, &pin_info, AUTH_PIN); @@ -1764,7 +1712,7 @@ auth_create_reference_data (sc_card_t *card, len += args->puk_len; } - sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 1, pin_ref); + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 1, args->ref); apdu.data = sbuf; apdu.datalen = len; apdu.lc = len; @@ -1780,9 +1728,9 @@ auth_create_reference_data (sc_card_t *card, static int -auth_logout(sc_card_t *card) +auth_logout(struct sc_card *card) { - sc_apdu_t apdu; + struct sc_apdu apdu; int ii, rv = 0, pin_ref; int reset_flag = 0x20; @@ -1790,12 +1738,8 @@ auth_logout(sc_card_t *card) rv = auth_get_pin_reference (card, SC_AC_CHV, ii+1, SC_PIN_CMD_UNBLOCK, &pin_ref); SC_TEST_RET(card->ctx, rv, "Cannot get PIN reference"); - sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2E, 0x00, 0x00); - apdu.cla = 0x80; - apdu.lc = 0x0; - apdu.le = 0x0; - apdu.resplen = 0; - apdu.resp = NULL; + sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2E, 0x00, 0x00); + apdu.cla = 0x80; apdu.p2 = pin_ref | reset_flag; rv = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); @@ -1805,14 +1749,15 @@ auth_logout(sc_card_t *card) SC_FUNC_RETURN(card->ctx, 1, rv); } + static int -write_publickey (sc_card_t *card, unsigned int offset, - const u8 *buf, size_t count) +write_publickey (struct sc_card *card, unsigned int offset, + const unsigned char *buf, size_t count) { - int ii, rv; - struct sc_pkcs15_pubkey_rsa key; - size_t len = 0, der_size = 0; struct auth_update_component_info args; + struct sc_pkcs15_pubkey_rsa key; + int ii, rv; + size_t len = 0, der_size = 0; SC_FUNC_CALLED(card->ctx, 1); if (card->ctx->debug >= 5) { @@ -1869,8 +1814,8 @@ write_publickey (sc_card_t *card, unsigned int offset, static int -auth_update_binary(sc_card_t *card, unsigned int offset, - const u8 *buf, size_t count, unsigned long flags) +auth_update_binary(struct sc_card *card, unsigned int offset, + const unsigned char *buf, size_t count, unsigned long flags) { int rv = 0; @@ -1892,8 +1837,7 @@ auth_update_binary(sc_card_t *card, unsigned int offset, memset(&args, 0, sizeof(args)); args.type = SC_CARDCTL_OBERTHUR_KEY_DES; - args.component = 0; - args.data = (u8 *)buf; + args.data = (unsigned char *)buf; args.len = count; rv = auth_update_component(card, &args); } @@ -1906,8 +1850,8 @@ auth_update_binary(sc_card_t *card, unsigned int offset, static int -auth_read_binary(sc_card_t *card, unsigned int offset, - u8 *buf, size_t count, unsigned long flags) +auth_read_binary(struct sc_card *card, unsigned int offset, + unsigned char *buf, size_t count, unsigned long flags) { int rv; @@ -1935,7 +1879,7 @@ auth_read_binary(sc_card_t *card, unsigned int offset, for (jj=0; jjctx, rv, "Cannot read RSA public key component"); - bn[1].data = (u8 *) malloc(rv); + bn[1].data = (unsigned char *) calloc(1, rv); bn[1].len = rv; memcpy(bn[1].data, resp, rv); @@ -1984,18 +1928,17 @@ auth_read_binary(sc_card_t *card, unsigned int offset, static int auth_read_record(struct sc_card *card, unsigned int nr_rec, - u8 *buf, size_t count, - unsigned long flags) + unsigned char *buf, size_t count, unsigned long flags) { - int rv = 0; struct sc_apdu apdu; - u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE]; + int rv = 0; + unsigned char recvbuf[SC_MAX_APDU_BUFFER_SIZE]; sc_debug(card->ctx, "auth_read_record(): nr_rec %i; count %i\n", nr_rec, count); - sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, nr_rec, 0); - apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3; - if (flags & SC_RECORD_BY_REC_NR) + sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xB2, nr_rec, 0); + apdu.p2 = (flags & SC_RECORD_EF_ID_MASK) << 3; + if (flags & SC_RECORD_BY_REC_NR) apdu.p2 |= 0x04; apdu.le = count; @@ -2016,20 +1959,16 @@ auth_read_record(struct sc_card *card, unsigned int nr_rec, static int -auth_delete_record(sc_card_t *card, unsigned int nr_rec) +auth_delete_record(struct sc_card *card, unsigned int nr_rec) { + struct sc_apdu apdu; int rv = 0; - sc_apdu_t apdu; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "auth_delete_record(): nr_rec %i\n", nr_rec); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x32, nr_rec, 0x04); apdu.cla = 0x80; - apdu.lc = 0x0; - apdu.le = 0x0; - apdu.resplen = 0; - apdu.resp = NULL; rv = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, rv, "APDU transmit failed"); @@ -2038,8 +1977,9 @@ auth_delete_record(sc_card_t *card, unsigned int nr_rec) SC_FUNC_RETURN(card->ctx, 1, rv); } + static int -auth_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) +auth_get_serialnr(struct sc_card *card, struct sc_serial_number *serial) { if (!card || !serial) SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS); @@ -2052,6 +1992,7 @@ auth_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS); } + static struct sc_card_driver * sc_get_driver(void) { @@ -2076,12 +2017,7 @@ sc_get_driver(void) auth_ops.compute_signature = auth_compute_signature; auth_ops.decipher = auth_decipher; auth_ops.process_fci = auth_process_fci; - - auth_ops.pin_cmd = NULL; - auth_ops.verify = auth_verify; - auth_ops.reset_retry_counter = auth_reset_retry_counter; - auth_ops.change_reference_data = auth_change_reference_data; - + auth_ops.pin_cmd = auth_pin_cmd; auth_ops.logout = auth_logout; return &auth_drv; } diff --git a/src/libopensc/card-rutoken.c b/src/libopensc/card-rutoken.c index af1e8025..1ba0c65c 100644 --- a/src/libopensc/card-rutoken.c +++ b/src/libopensc/card-rutoken.c @@ -97,7 +97,8 @@ static struct sc_card_driver rutoken_drv = { }; static struct sc_atr_table rutoken_atrs[] = { - { "3b:6f:00:ff:00:56:72:75:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, + { "3b:6f:00:ff:00:56:72:75:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, /* Aktiv Rutoken S */ + { "3b:6f:00:ff:00:56:75:61:54:6f:6b:6e:73:30:20:00:00:90:00", NULL, NULL, SC_CARD_TYPE_GENERIC_BASE, 0, NULL }, /* Aktiv uaToken S */ { NULL, NULL, NULL, 0, 0, NULL } }; @@ -162,7 +163,11 @@ static int rutoken_init(sc_card_t *card) int ret; SC_FUNC_CALLED(card->ctx, 1); - ret = token_init(card, "Rutoken card"); + /* &rutoken_atrs[1] : { uaToken S ATR, NULL ATR } */ + if (_sc_match_atr(card, &rutoken_atrs[1], &card->type) >= 0) + ret = token_init(card, "uaToken S card"); + else + ret = token_init(card, "Rutoken S card"); SC_FUNC_RETURN(card->ctx, 1, ret); } diff --git a/src/libopensc/libopensc.exports b/src/libopensc/libopensc.exports index af3d7ade..405859d0 100644 --- a/src/libopensc/libopensc.exports +++ b/src/libopensc/libopensc.exports @@ -164,6 +164,8 @@ sc_pkcs15_read_data_object sc_pkcs15_read_file sc_pkcs15_read_prkey sc_pkcs15_read_pubkey +sc_pkcs15_pubkey_from_prvkey +sc_pkcs15_pubkey_from_cert sc_pkcs15_remove_df sc_pkcs15_remove_object sc_pkcs15_remove_unusedspace diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h index 39898914..6c099b68 100644 --- a/src/libopensc/opensc.h +++ b/src/libopensc/opensc.h @@ -111,6 +111,12 @@ extern "C" { #define SC_AC_OP_WRITE 3 /* rehab and invalidate are the same as in DF case */ +/* Special 'Oberthur IdOne AuthentIC's case: + * re-use the existing DF ACLs that are not relevant to this card. */ +#define SC_AC_OP_PIN_DEFINE SC_AC_OP_LOCK +#define SC_AC_OP_PIN_CHANGE SC_AC_OP_REHABILITATE +#define SC_AC_OP_PIN_RESET SC_AC_OP_DELETE_SELF + /* various maximum values */ #define SC_MAX_READER_DRIVERS 6 #define SC_MAX_READERS 16 diff --git a/src/libopensc/pkcs15-pubkey.c b/src/libopensc/pkcs15-pubkey.c index 507fa546..8fd1f2ad 100644 --- a/src/libopensc/pkcs15-pubkey.c +++ b/src/libopensc/pkcs15-pubkey.c @@ -26,6 +26,12 @@ #include #include +#ifdef ENABLE_OPENSSL +#include +#include +#endif + + static const struct sc_asn1_entry c_asn1_com_key_attr[] = { { "iD", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL }, { "usage", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL }, @@ -36,7 +42,7 @@ static const struct sc_asn1_entry c_asn1_com_key_attr[] = { }; static const struct sc_asn1_entry c_asn1_com_pubkey_attr[] = { - /* FIXME */ + /* FIXME */ { NULL, 0, 0, 0, NULL, NULL } }; @@ -63,7 +69,7 @@ static const struct sc_asn1_entry c_asn1_dsa_type_attr[] = { }; static const struct sc_asn1_entry c_asn1_gostr3410key_attr[] = { - { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, + { "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL }, { "params_r3410", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL }, { "params_r3411", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, { "params_28147", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL }, @@ -556,26 +562,168 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card, return 0; } +static int +sc_pkcs15_dup_bignum (struct sc_pkcs15_bignum *dst, struct sc_pkcs15_bignum *src) +{ + assert(dst && src); + + if (src->data && src->len) { + dst->data = calloc(1, src->len); + if (!dst->data) + return SC_ERROR_OUT_OF_MEMORY; + memcpy(dst->data, src->data, src->len); + dst->len = src->len; + } + + return 0; +} + +int +sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx, + struct sc_pkcs15_prkey *prvkey, struct sc_pkcs15_pubkey **out) +{ + struct sc_pkcs15_pubkey *pubkey; + int rv = SC_SUCCESS; + + assert(prvkey && out); + + *out = NULL; + pubkey = (struct sc_pkcs15_pubkey *) calloc(1, sizeof(struct sc_pkcs15_pubkey)); + if (!pubkey) + return SC_ERROR_OUT_OF_MEMORY; + + pubkey->algorithm = prvkey->algorithm; + switch (prvkey->algorithm) { + case SC_ALGORITHM_RSA: + rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.modulus, &prvkey->u.rsa.modulus); + if (!rv) + rv = sc_pkcs15_dup_bignum(&pubkey->u.rsa.exponent, &prvkey->u.rsa.exponent); + break; + case SC_ALGORITHM_DSA: + rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.pub, &prvkey->u.dsa.pub); + if (!rv) + rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.p, &prvkey->u.dsa.p); + if (!rv) + rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.q, &prvkey->u.dsa.q); + if (!rv) + rv = sc_pkcs15_dup_bignum(&pubkey->u.dsa.g, &prvkey->u.dsa.g); + break; + case SC_ALGORITHM_GOSTR3410: + break; + default: + sc_debug(ctx, "Unsupported private key algorithm"); + return SC_ERROR_NOT_SUPPORTED; + } + + if (rv) + sc_pkcs15_free_pubkey(pubkey); + else + *out = pubkey; + + return SC_SUCCESS; +} + + +int +sc_pkcs15_pubkey_from_cert(struct sc_context *ctx, + struct sc_pkcs15_der *cert_blob, struct sc_pkcs15_pubkey **out) +{ +#ifndef ENABLE_OPENSSL + SC_FUNC_RETURN(ctx, 1, SC_ERROR_NOT_SUPPORTED); +#else + EVP_PKEY *pkey = NULL; + X509 *x = NULL; + BIO *mem = NULL; + struct sc_pkcs15_pubkey *pubkey = NULL; + int rv = 0; + + assert(cert_blob && out); + + pubkey = (struct sc_pkcs15_pubkey *) calloc(1, sizeof(struct sc_pkcs15_pubkey)); + if (!pubkey) + SC_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate pubkey"); + + pubkey->algorithm = SC_ALGORITHM_RSA; + do { + rv = SC_ERROR_INVALID_DATA; + mem = BIO_new_mem_buf(cert_blob->value, cert_blob->len); + if (!mem) + break; + + x = d2i_X509_bio(mem, NULL); + if (!x) + break; + + pkey=X509_get_pubkey(x); + if (!pkey || pkey->type != EVP_PKEY_RSA) + break; + + pubkey->u.rsa.modulus.len = BN_num_bytes(pkey->pkey.rsa->n); + pubkey->u.rsa.modulus.data = calloc(1, pubkey->u.rsa.modulus.len); + + pubkey->u.rsa.exponent.len = BN_num_bytes(pkey->pkey.rsa->e); + pubkey->u.rsa.exponent.data = calloc(1, pubkey->u.rsa.exponent.len); + + rv = SC_ERROR_OUT_OF_MEMORY; + if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.exponent.data) + break; + + BN_bn2bin(pkey->pkey.rsa->n, pubkey->u.rsa.modulus.data); + BN_bn2bin(pkey->pkey.rsa->e, pubkey->u.rsa.exponent.data); + + rv = SC_SUCCESS; + } while (0); + + if (pkey) + EVP_PKEY_free(pkey); + + if (x) + X509_free(x); + + if (mem) + BIO_free(mem); + + if (rv) { + sc_pkcs15_free_pubkey(pubkey); + pubkey = NULL; + } + + *out = pubkey; + + SC_FUNC_RETURN(ctx, 1, rv); +#endif +} + + void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *key) { assert(key != NULL); switch (key->algorithm) { case SC_ALGORITHM_RSA: - free(key->u.rsa.modulus.data); - free(key->u.rsa.exponent.data); + if (key->u.rsa.modulus.data) + free(key->u.rsa.modulus.data); + if (key->u.rsa.exponent.data) + free(key->u.rsa.exponent.data); break; case SC_ALGORITHM_DSA: - free(key->u.dsa.pub.data); - free(key->u.dsa.g.data); - free(key->u.dsa.p.data); - free(key->u.dsa.q.data); + if (key->u.dsa.pub.data) + free(key->u.dsa.pub.data); + if (key->u.dsa.g.data) + free(key->u.dsa.g.data); + if (key->u.dsa.p.data) + free(key->u.dsa.p.data); + if (key->u.dsa.q.data) + free(key->u.dsa.q.data); break; case SC_ALGORITHM_GOSTR3410: - free(key->u.gostr3410.x.data); - free(key->u.gostr3410.y.data); + if (key->u.gostr3410.x.data) + free(key->u.gostr3410.x.data); + if (key->u.gostr3410.y.data) + free(key->u.gostr3410.y.data); break; } - free(key->data.value); + if (key->data.value) + free(key->data.value); sc_mem_clear(key, sizeof(*key)); } diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c index 7b5deb32..abca41a1 100644 --- a/src/libopensc/pkcs15-syn.c +++ b/src/libopensc/pkcs15-syn.c @@ -149,7 +149,7 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card) } } } - if (builtin_enabled) { + else if (builtin_enabled) { sc_debug(ctx, "no emulator list in config file, trying all builtin emulators\n"); for (i = 0; builtin_emulators[i].name; i++) { sc_debug(ctx, "trying %s\n", builtin_emulators[i].name); diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index 9188ec8e..b83bae19 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -759,8 +759,8 @@ done: if (strcmp(p15card->card->driver->short_name,"cardos") == 0) { /* D-Trust cards (D-TRUST, D-SIGN) */ - if (strstr(p15card->label,"D-TRUST") == 0 - || strstr(p15card->label,"D-SIGN") == 0) { + if (strstr(p15card->label,"D-TRUST") != NULL + || strstr(p15card->label,"D-SIGN") != NULL) { /* D-TRUST Card 2.0 2cc (standard cards, which always add * SHA1 prefix itself */ diff --git a/src/libopensc/pkcs15.h b/src/libopensc/pkcs15.h index 1ab2c3a6..ee33065d 100644 --- a/src/libopensc/pkcs15.h +++ b/src/libopensc/pkcs15.h @@ -434,12 +434,14 @@ typedef struct sc_pkcs15_card { char *preferred_language; } sc_pkcs15_card_t; -#define SC_PKCS15_CARD_FLAG_READONLY 0x01 -#define SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED 0x02 -#define SC_PKCS15_CARD_FLAG_PRN_GENERATION 0x04 -#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08 -#define SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT 0x10 -#define SC_PKCS15_CARD_FLAG_EMULATED 0x20 +#define SC_PKCS15_CARD_FLAG_READONLY 0x01 +#define SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED 0x02 +#define SC_PKCS15_CARD_FLAG_PRN_GENERATION 0x04 +#define SC_PKCS15_CARD_FLAG_EID_COMPLIANT 0x08 +#define SC_PKCS15_CARD_FLAG_SIGN_WITH_DECRYPT 0x10 +#define SC_PKCS15_CARD_FLAG_EMULATED 0x20 +#define SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED 0x40 +#define SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED 0x80 /* sc_pkcs15_bind: Binds a card object to a PKCS #15 card object * and initializes a new PKCS #15 card object. Will return @@ -475,16 +477,16 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card, unsigned long alg_flags, const u8 *in, size_t inlen, u8 *out, size_t outlen); -int sc_pkcs15_read_pubkey(struct sc_pkcs15_card *card, - const struct sc_pkcs15_object *obj, - struct sc_pkcs15_pubkey **out); -int sc_pkcs15_decode_pubkey_rsa(struct sc_context *ctx, - struct sc_pkcs15_pubkey_rsa *pubkey, +int sc_pkcs15_read_pubkey(struct sc_pkcs15_card *, + const struct sc_pkcs15_object *, + struct sc_pkcs15_pubkey **); +int sc_pkcs15_decode_pubkey_rsa(struct sc_context *, + struct sc_pkcs15_pubkey_rsa *, const u8 *, size_t); int sc_pkcs15_encode_pubkey_rsa(struct sc_context *, struct sc_pkcs15_pubkey_rsa *, u8 **, size_t *); -int sc_pkcs15_decode_pubkey_dsa(struct sc_context *ctx, - struct sc_pkcs15_pubkey_dsa *pubkey, +int sc_pkcs15_decode_pubkey_dsa(struct sc_context *, + struct sc_pkcs15_pubkey_dsa *, const u8 *, size_t); int sc_pkcs15_encode_pubkey_dsa(struct sc_context *, struct sc_pkcs15_pubkey_dsa *, u8 **, size_t *); @@ -492,13 +494,16 @@ int sc_pkcs15_decode_pubkey(struct sc_context *, struct sc_pkcs15_pubkey *, const u8 *, size_t); int sc_pkcs15_encode_pubkey(struct sc_context *, struct sc_pkcs15_pubkey *, u8 **, size_t *); -void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *pubkey); -void sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *pubkey); - -int sc_pkcs15_read_prkey(struct sc_pkcs15_card *card, - const struct sc_pkcs15_object *obj, +void sc_pkcs15_erase_pubkey(struct sc_pkcs15_pubkey *); +void sc_pkcs15_free_pubkey(struct sc_pkcs15_pubkey *); +int sc_pkcs15_pubkey_from_prvkey(struct sc_context *, struct sc_pkcs15_prkey *, + struct sc_pkcs15_pubkey **); +int sc_pkcs15_pubkey_from_cert(struct sc_context *, struct sc_pkcs15_der *, + struct sc_pkcs15_pubkey **); +int sc_pkcs15_read_prkey(struct sc_pkcs15_card *, + const struct sc_pkcs15_object *, const char *passphrase, - struct sc_pkcs15_prkey **out); + struct sc_pkcs15_prkey **); int sc_pkcs15_decode_prkey(struct sc_context *, struct sc_pkcs15_prkey *, const u8 *, size_t); diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index cf47e19e..48b3dc77 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1735,12 +1735,23 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, goto kpgen_done; } - /* Write the new public and private keys to the pkcs15 files */ - rc = sc_pkcs15init_store_private_key(p15card, profile, - &keygen_args.prkey_args, &priv_key_obj); - if (rc >= 0) - rc = sc_pkcs15init_store_public_key(p15card, profile, - &pub_args, &pub_key_obj); + /* Write the new public and private keys to the pkcs15 files */ + /* To support smartcards that require different keybobjects for signing and encryption */ + if (sc_pkcs15init_requires_restrictive_usage(p15card, &keygen_args.prkey_args, 0)) { + sc_debug(context, "store split key required for this card", rv); + /* second key is the signature keyobject */ + rc = sc_pkcs15init_store_split_key(p15card, profile, &keygen_args.prkey_args, NULL, &priv_key_obj); + } + else { + rc = sc_pkcs15init_store_private_key(p15card, profile, &keygen_args.prkey_args, &priv_key_obj); + } + + if (rc >= 0) { + /* copy ID from private key(s) here to avoid bad link between private and public key */ + memcpy(&pub_args.id.value, &keygen_args.prkey_args.id.value, keygen_args.prkey_args.id.len); + pub_args.id.len = keygen_args.prkey_args.id.len; + rc = sc_pkcs15init_store_public_key(p15card, profile, &pub_args, &pub_key_obj); + } if (rc < 0) { sc_debug(context, "private/public keys not stored: %d\n", rc); rv = sc_to_cryptoki_error(rc, p11card->reader); diff --git a/src/pkcs15init/oberthur.profile b/src/pkcs15init/oberthur.profile index 4a6382ef..074f2d82 100644 --- a/src/pkcs15init/oberthur.profile +++ b/src/pkcs15init/oberthur.profile @@ -53,8 +53,9 @@ filesystem { DF OberthurAWP-AppDF { ACL = *=NONE; - #ACL = CREATE=CHV4, CRYPTO=NEVER, PIN_SET=CHV4, PIN_RESET=PRO0x78; - ACL = CREATE=CHV4, CRYPTO=NEVER; + #ACL = CREATE=CHV4, CRYPTO=NEVER, PIN_SET=CHV4, PIN_RESET=PRO0x78; + ACL = CREATE=CHV4, CRYPTO=NEVER, PIN-DEFINE=CHV4, PIN-RESET=CHV4; + #ACL = CREATE=CHV4, CRYPTO=NEVER; file-id = 5011; size = 40; diff --git a/src/pkcs15init/pkcs15-init.h b/src/pkcs15init/pkcs15-init.h index f993937d..9b99d2b5 100644 --- a/src/pkcs15init/pkcs15-init.h +++ b/src/pkcs15init/pkcs15-init.h @@ -175,6 +175,10 @@ struct sc_pkcs15init_operations { }; /* Do not change these or reorder these */ +#define SC_PKCS15INIT_ID_STYLE_NATIVE 0 +#define SC_PKCS15INIT_ID_STYLE_MOZILLA 1 +#define SC_PKCS15INIT_ID_STYLE_RFC2459 2 + #define SC_PKCS15INIT_SO_PIN 0 #define SC_PKCS15INIT_SO_PUK 1 #define SC_PKCS15INIT_USER_PIN 2 diff --git a/src/pkcs15init/pkcs15-lib.c b/src/pkcs15init/pkcs15-lib.c index de65352e..7cd39a55 100644 --- a/src/pkcs15init/pkcs15-lib.c +++ b/src/pkcs15init/pkcs15-lib.c @@ -119,6 +119,8 @@ static int check_key_compatibility(struct sc_pkcs15_card *, static int prkey_fixup(sc_pkcs15_card_t *, sc_pkcs15_prkey_t *); static int prkey_bits(sc_pkcs15_card_t *, sc_pkcs15_prkey_t *); static int prkey_pkcs15_algo(sc_pkcs15_card_t *, sc_pkcs15_prkey_t *); +static int select_intrinsic_id(sc_pkcs15_card_t *, struct sc_profile *, + int, sc_pkcs15_id_t *, void *); static int select_id(sc_pkcs15_card_t *, int, sc_pkcs15_id_t *, int (*)(const sc_pkcs15_object_t *, void *), void *, sc_pkcs15_object_t **); @@ -1220,8 +1222,8 @@ sc_pkcs15init_init_prkdf(sc_pkcs15_card_t *p15card, /* Split key; this ID exists already, don't check for * the pkcs15 object */ } else { - /* Select a Key ID if the user didn't specify one, otherwise - * make sure it's compatible with our intended use */ + /* Select a Key ID if the user didn't specify one, + * otherwise make sure it's compatible with our intended use */ r = select_id(p15card, SC_PKCS15_TYPE_PRKEY, &keyargs->id, can_reuse_prkey_obj, object, res_obj); if (r < 0) @@ -1302,7 +1304,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_pkcs15init_pubkeyargs pubkey_args; struct sc_pkcs15_object *object; struct sc_pkcs15_prkey_info *key_info; - int r; + int r, caller_supplied_id = 0; /* check supported key size */ r = check_key_size(p15card->card, keygen_args->prkey_args.key.algorithm, keybits); @@ -1328,6 +1330,8 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, if ((r = set_so_pin_from_card(p15card, profile)) < 0) return r; + caller_supplied_id = keygen_args->prkey_args.id.len != 0; + /* Set up the PrKDF object */ r = sc_pkcs15init_init_prkdf(p15card, profile, &keygen_args->prkey_args, &keygen_args->prkey_args.key, keybits, &object); @@ -1342,7 +1346,7 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, #if 0 pubkey_args.auth_id = keygen_args->prkey_args.auth_id; #endif - pubkey_args.label = keygen_args->pubkey_label; + pubkey_args.label = keygen_args->pubkey_label ? keygen_args->pubkey_label : object->label; pubkey_args.usage = keygen_args->prkey_args.usage; pubkey_args.x509_usage = keygen_args->prkey_args.x509_usage; pubkey_args.gost_params = keygen_args->prkey_args.gost_params; @@ -1368,8 +1372,23 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, /* update PrKDF entry */ if (r >= 0) { - r = sc_pkcs15init_add_object(p15card, profile, - SC_PKCS15_PRKDF, object); + if (!caller_supplied_id) { + struct sc_pkcs15_id iid; + + /* Caller not supplied ID, so, + * if intrinsic ID can be calculated -- overwrite the native one */ + memset(&iid, 0, sizeof(iid)); + r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &iid, &pubkey_args.key); + if (r < 0) + return r; + + if (iid.len) { + key_info->id = iid; + pubkey_args.id = iid; + } + } + + r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object); } if (r >= 0) { @@ -1439,6 +1458,11 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, if ((r = set_so_pin_from_card(p15card, profile)) < 0) return r; + /* Select a intrinsic Key ID if user didn't specify one */ + r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PRKEY, &keyargs->id, &keyargs->key); + if (r < 0) + return r; + /* Set up the PrKDF object */ r = sc_pkcs15init_init_prkdf(p15card, profile, keyargs, &key, keybits, &object); if (r < 0) @@ -1649,9 +1673,14 @@ sc_pkcs15init_store_public_key(struct sc_pkcs15_card *p15card, keyinfo_gostparams->gost28147 = keyargs->gost_params.gost28147; } - /* Select a Key ID if the user didn't specify one, otherwise - * make sure it's unique */ *res_obj = NULL; + /* Select a intrinsic Key ID if the user didn't specify one */ + r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_PUBKEY, &keyargs->id, &key); + if (r < 0) + return r; + + /* Select a Key ID if the user didn't specify one and there is no intrinsic ID, + * otherwise make sure it's unique */ r = select_id(p15card, SC_PKCS15_TYPE_PUBKEY, &keyargs->id, can_reuse_pubkey_obj, object, res_obj); if (r < 0) @@ -1728,6 +1757,10 @@ sc_pkcs15init_store_certificate(struct sc_pkcs15_card *p15card, if ((r = set_so_pin_from_card(p15card, profile)) < 0) return r; + r = select_intrinsic_id(p15card, profile, SC_PKCS15_TYPE_CERT_X509, &args->id, &args->der_encoded); + if (r < 0) + return r; + /* Select an ID if the user didn't specify one, otherwise * make sure it's unique */ if ((r = select_id(p15card, SC_PKCS15_TYPE_CERT, &args->id, NULL, NULL, NULL)) < 0) @@ -1992,7 +2025,7 @@ static size_t sc_pkcs15init_keybits(sc_pkcs15_bignum_t *bn) if (!bn || !bn->len) return 0; bits = bn->len << 3; - for (mask = 0x80; !(bn->data[0] & mask); mask >>= 1) + for (mask = 0x80; mask && !(bn->data[0] & mask); mask >>= 1) bits--; return bits; } @@ -2247,6 +2280,102 @@ find_df_by_type(struct sc_pkcs15_card *p15card, unsigned int type) return df; } +static int select_intrinsic_id(sc_pkcs15_card_t *p15card, struct sc_profile *profile, + int type, sc_pkcs15_id_t *id, void *data) +{ + struct sc_context *ctx = p15card->card->ctx; + struct sc_pkcs15_pubkey *pubkey = NULL; + unsigned id_style = profile->id_style; + int rv, allocated = 0; + + SC_FUNC_CALLED(ctx, 1); +#ifndef ENABLE_OPENSSL + SC_FUNC_RETURN(ctx, 1, 0); +#else + /* ID already exists */ + if (id->len) + SC_FUNC_RETURN(ctx, 1, 0); + + /* Native ID style is not an intrisic one */ + if (profile->id_style == SC_PKCS15INIT_ID_STYLE_NATIVE) + SC_FUNC_RETURN(ctx, 1, 0); + + /* Get PKCS15 public key */ + switch(type) { + case SC_PKCS15_TYPE_CERT_X509: + rv = sc_pkcs15_pubkey_from_cert(ctx, (struct sc_pkcs15_der *)data, &pubkey); + SC_TEST_RET(ctx, rv, "X509 parse error"); + + allocated = 1; + break; + case SC_PKCS15_TYPE_PRKEY: + rv = sc_pkcs15_pubkey_from_prvkey(ctx, (struct sc_pkcs15_prkey *)data, &pubkey); + SC_TEST_RET(ctx, rv, "Cannot get public key"); + + allocated = 1; + break; + case SC_PKCS15_TYPE_PUBKEY: + pubkey = (struct sc_pkcs15_pubkey *)data; + + allocated = 0; + break; + default: + sc_debug(ctx, "Intrinsic ID is not implemented for the object type 0x%X\n", type); + SC_FUNC_RETURN(ctx, 1, 0); + } + + /* Skip silently if key is not inintialized. */ + if (pubkey->algorithm == SC_ALGORITHM_RSA && !pubkey->u.rsa.modulus.len) + goto done; + else if (pubkey->algorithm == SC_ALGORITHM_DSA && !pubkey->u.dsa.pub.data) + goto done; + else if (pubkey->algorithm == SC_ALGORITHM_GOSTR3410 && + (!pubkey->u.gostr3410.x.data || !pubkey->u.gostr3410.y.data)) + goto done; + + /* In Mozilla 'GOST R 34.10' is not yet supported. + * So, switch to the ID recommended by RFC2459 */ + if (pubkey->algorithm == SC_ALGORITHM_GOSTR3410 && id_style == SC_PKCS15INIT_ID_STYLE_MOZILLA) + id_style = SC_PKCS15INIT_ID_STYLE_RFC2459; + + if (id_style == SC_PKCS15INIT_ID_STYLE_MOZILLA) { + if (pubkey->algorithm == SC_ALGORITHM_RSA) + SHA1(pubkey->u.rsa.modulus.data, pubkey->u.rsa.modulus.len, id->value); + else if (pubkey->algorithm == SC_ALGORITHM_DSA) + SHA1(pubkey->u.dsa.pub.data, pubkey->u.dsa.pub.len, id->value); + else + goto done; + + id->len = SHA_DIGEST_LENGTH; + } + else if (id_style == SC_PKCS15INIT_ID_STYLE_RFC2459) { + unsigned char *id_data = NULL; + size_t id_data_len = 0; + + rv = sc_pkcs15_encode_pubkey(ctx, pubkey, &id_data, &id_data_len); + SC_TEST_RET(ctx, rv, "Encoding public key error"); + + if (!id_data || !id_data_len) + SC_TEST_RET(ctx, SC_ERROR_INTERNAL, "Encoding public key error"); + + SHA1(id_data, id_data_len, id->value); + id->len = SHA_DIGEST_LENGTH; + + free(id_data); + } + else { + sc_debug(ctx, "Unsupported ID style: %i", profile->id_style); + SC_TEST_RET(ctx, SC_ERROR_NOT_SUPPORTED, "Non supported ID style"); + } + +done: + if (allocated) + sc_pkcs15_free_pubkey(pubkey); + + SC_FUNC_RETURN(ctx, 1, id->len); +#endif +} + static int select_id(sc_pkcs15_card_t *p15card, int type, sc_pkcs15_id_t *id, int (*can_reuse)(const sc_pkcs15_object_t *, void *), void *data, sc_pkcs15_object_t **reuse_obj) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index 437e96c2..bc45bba5 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -47,7 +47,7 @@ #define COSM_TITLE "OberthurAWP" #define TLV_TYPE_V 0 -#define TLV_TYPE_LV 1 +#define TLV_TYPE_LV 1 #define TLV_TYPE_TLV 2 /* Should be greater then SC_PKCS15_TYPE_CLASS_MASK */ @@ -56,19 +56,133 @@ #define COSM_TYPE_PRKEY_RSA (SC_DEVICE_SPECIFIC_TYPE | SC_PKCS15_TYPE_PRKEY_RSA) #define COSM_TYPE_PUBKEY_RSA (SC_DEVICE_SPECIFIC_TYPE | SC_PKCS15_TYPE_PUBKEY_RSA) +#define COSM_TOKEN_FLAG_PRN_GENERATION 0x01 +#define COSM_TOKEN_FLAG_LOGIN_REQUIRED 0x04 +#define COSM_TOKEN_FLAG_USER_PIN_INITIALIZED 0x08 +#define COSM_TOKEN_FLAG_TOKEN_INITIALIZED 0x0400 -static int cosm_update_pin(struct sc_profile *profile, sc_card_t *card, - struct sc_pkcs15_pin_info *info, const u8 *pin, size_t pin_len, - const u8 *puk, size_t puk_len); +static int cosm_create_reference_data(struct sc_profile *, struct sc_card *, + struct sc_pkcs15_pin_info *, + const unsigned char *pin, size_t pin_len, + const unsigned char *puk, size_t puk_len); +static int cosm_update_pin(struct sc_profile *profile, struct sc_card *card, + struct sc_pkcs15_pin_info *info, const unsigned char *pin, size_t pin_len, + const unsigned char *puk, size_t puk_len); -int cosm_delete_file(sc_card_t *card, struct sc_profile *profile, - sc_file_t *df); +int cosm_delete_file(struct sc_card *card, struct sc_profile *profile, + struct sc_file *df); -int cosm_delete_file(sc_card_t *card, struct sc_profile *profile, - sc_file_t *df) + +static int +cosm_write_tokeninfo (struct sc_card *card, struct sc_profile *profile, + char *label, unsigned p15_flags) { - sc_path_t path; - sc_file_t *parent; + struct sc_file *file = NULL; + unsigned mask = SC_PKCS15_CARD_FLAG_PRN_GENERATION + | SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED + | SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED + | SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED; + int rv, sz, flags = 0; + char *buffer = NULL; + + if (!card || !profile) + return SC_ERROR_INVALID_ARGUMENTS; + + SC_FUNC_CALLED(card->ctx, 1); + sc_debug(card->ctx, "cosm_write_tokeninfo() label '%s'; flags 0x%X\n", label, p15_flags); + if (sc_profile_get_file(profile, COSM_TITLE"-token-info", &file)) + SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Cannot find "COSM_TITLE"-token-info"); + + if (file->size < 16) + SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Unsufficient size of the "COSM_TITLE"-token-info file"); + + buffer = calloc(1, file->size); + if (!buffer) + SC_TEST_RET(card->ctx, SC_ERROR_MEMORY_FAILURE, "Allocation error in cosm_write_tokeninfo()"); + + if (label) + strncpy(buffer, label, file->size - 4); + else if (profile->p15_data && profile->p15_data->label) + snprintf(buffer, file->size - 4, profile->p15_data->label); + else if (profile->p15_spec && profile->p15_spec->label) + snprintf(buffer, file->size - 4, profile->p15_spec->label); + else + snprintf(buffer, file->size - 4, "OpenSC-Token"); + + sz = strlen(buffer); + if (sz < file->size - 4) + memset(buffer + sz, ' ', file->size - sz); + + if (p15_flags & SC_PKCS15_CARD_FLAG_PRN_GENERATION) + flags |= COSM_TOKEN_FLAG_PRN_GENERATION; + + if (p15_flags & SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED) + flags |= COSM_TOKEN_FLAG_LOGIN_REQUIRED; + + if (p15_flags & SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED) + flags |= COSM_TOKEN_FLAG_USER_PIN_INITIALIZED; + + if (p15_flags & SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED) + flags |= COSM_TOKEN_FLAG_TOKEN_INITIALIZED; + + sc_debug(card->ctx, "cosm_write_tokeninfo() token label '%s'; oberthur flags 0x%X\n", buffer, flags); + + memset(buffer + file->size - 4, 0, 4); + *(buffer + file->size - 1) = flags & 0xFF; + *(buffer + file->size - 2) = (flags >> 8) & 0xFF; + + rv = sc_pkcs15init_update_file(profile, card, file, buffer, file->size); + if (rv > 0) + rv = 0; + + if (profile->p15_data) + profile->p15_data->flags = (profile->p15_data->flags & ~mask) | p15_flags; + + if (profile->p15_spec) + profile->p15_spec->flags = (profile->p15_spec->flags & ~mask) | p15_flags; + + free(buffer); + SC_FUNC_RETURN(card->ctx, 1, rv); +} + + +static int +cosm_update_pukfile (struct sc_card *card, struct sc_profile *profile, + unsigned char *data, size_t data_len) +{ + struct sc_pkcs15_pin_info profile_puk; + struct sc_file *file = NULL; + int rv, sz, flags = 0; + unsigned char buffer[16]; + + SC_FUNC_CALLED(card->ctx, 1); + if (!data || data_len > 16) + return SC_ERROR_INVALID_ARGUMENTS; + + sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PUK, &profile_puk); + if (profile_puk.max_length > 16) + SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Invalid PUK settings"); + + if (sc_profile_get_file(profile, COSM_TITLE"-puk-file", &file)) + SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Cannot find PUKFILE"); + + memset(buffer, profile_puk.pad_char, 16); + memcpy(buffer, data, data_len); + + rv = sc_pkcs15init_update_file(profile, card, file, buffer, sizeof(buffer)); + if (rv > 0) + rv = 0; + + SC_FUNC_RETURN(card->ctx, 1, rv); +} + + +int +cosm_delete_file(struct sc_card *card, struct sc_profile *profile, + struct sc_file *df) +{ + struct sc_path path; + struct sc_file *parent; int rv = 0; SC_FUNC_CALLED(card->ctx, 1); @@ -104,9 +218,10 @@ int cosm_delete_file(sc_card_t *card, struct sc_profile *profile, /* * Erase the card */ -static int cosm_erase_card(struct sc_profile *profile, sc_card_t *card) +static int +cosm_erase_card(struct sc_profile *profile, struct sc_card *card) { - sc_file_t *df = profile->df_info->file, *dir; + struct sc_file *df = profile->df_info->file, *dir; int rv; SC_FUNC_CALLED(card->ctx, 1); @@ -150,6 +265,7 @@ static int cosm_erase_card(struct sc_profile *profile, sc_card_t *card) sc_file_free(dir); } + sc_free_apps(card); done: sc_keycache_forget_key(NULL, -1, -1); @@ -164,14 +280,14 @@ done: * Initialize the Application DF */ static int -cosm_init_app(struct sc_profile *profile, sc_card_t *card, +cosm_init_app(struct sc_profile *profile, struct sc_card *card, struct sc_pkcs15_pin_info *pinfo, - const u8 *pin, size_t pin_len, - const u8 *puk, size_t puk_len) + const unsigned char *pin, size_t pin_len, + const unsigned char *puk, size_t puk_len) { - int rv; + struct sc_file *file = NULL; size_t ii; - sc_file_t *file = NULL; + int rv; static const char *create_dfs[] = { COSM_TITLE"-AppDF", "private-DF", @@ -192,7 +308,7 @@ cosm_init_app(struct sc_profile *profile, sc_card_t *card, }; SC_FUNC_CALLED(card->ctx, 1); - sc_debug(card->ctx, "pin_len %i; puk_len %i\n", pin_len, puk_len); + sc_debug(card->ctx, "cosm_init_app() pin_len %i; puk_len %i\n", pin_len, puk_len); /* Oberthur AWP file system is expected.*/ /* Create private objects DF */ @@ -206,22 +322,43 @@ cosm_init_app(struct sc_profile *profile, sc_card_t *card, sc_debug(card->ctx, "rv %i\n", rv); sc_file_free(file); if (rv && rv!=SC_ERROR_FILE_ALREADY_EXISTS) - SC_TEST_RET(card->ctx, rv, "sc_pkcs15init_create_file() failed"); + SC_TEST_RET(card->ctx, rv, "cosm_init_app() sc_pkcs15init_create_file failed"); } - SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS); + rv = cosm_write_tokeninfo(card, profile, NULL, + SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED | SC_PKCS15_CARD_FLAG_PRN_GENERATION); + + if (pin && pin_len) { + /* Create local SOPIN */ + struct sc_pkcs15_pin_info pin_info; + + sc_profile_get_file(profile, COSM_TITLE"-AppDF", &file); + + pin_info.flags = SC_PKCS15_PIN_FLAG_SO_PIN; + pin_info.reference = 4; + memcpy(&pin_info.path, &file->path, sizeof(pin_info.path)); + + sc_file_free(file); + + rv = cosm_create_reference_data(profile, card, &pin_info, pin, pin_len, NULL, 0); + SC_TEST_RET(card->ctx, rv, "cosm_init_app() cosm_update_pin failed"); + } + + SC_FUNC_RETURN(card->ctx, 1, rv); } -static int cosm_create_reference_data(struct sc_profile *profile, sc_card_t *card, + +static int +cosm_create_reference_data(struct sc_profile *profile, struct sc_card *card, struct sc_pkcs15_pin_info *pinfo, - const u8 *pin, size_t pin_len, const u8 *puk, size_t puk_len ) + const unsigned char *pin, size_t pin_len, + const unsigned char *puk, size_t puk_len ) { - int rv; - int puk_buff_len = 0; - unsigned char *puk_buff = NULL; - sc_pkcs15_pin_info_t profile_pin; - sc_pkcs15_pin_info_t profile_puk; + struct sc_pkcs15_pin_info profile_pin; + struct sc_pkcs15_pin_info profile_puk; struct sc_cardctl_oberthur_createpin_info args; + unsigned char *puk_buff = NULL; + int rv, puk_buff_len = 0; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "pin lens %i/%i\n", pin_len, puk_len); @@ -233,9 +370,14 @@ static int cosm_create_reference_data(struct sc_profile *profile, sc_card_t *car rv = sc_select_file(card, &pinfo->path, NULL); SC_TEST_RET(card->ctx, rv, "Cannot select file"); - sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_pin); + if (pinfo->flags & SC_PKCS15_PIN_FLAG_SO_PIN) + sc_profile_get_pin_info(profile, SC_PKCS15INIT_SO_PIN, &profile_pin); + else + sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &profile_pin); + if (profile_pin.max_length > 0x100) - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INCONSISTENT_PROFILE); + SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "Invalid (SO)PIN profile settings"); + if (puk) { int ii, jj; @@ -277,7 +419,13 @@ static int cosm_create_reference_data(struct sc_profile *profile, sc_card_t *car args.puk_len = puk_buff_len; args.puk_tries = profile_puk.tries_left; - rv = sc_card_ctl(card, SC_CARDCTL_OBERTHUR_CREATE_PIN, &args); + rv = sc_card_ctl(card, SC_CARDCTL_OBERTHUR_CREATE_PIN, &args); + SC_TEST_RET(card->ctx, rv, "'CREATE_PIN' card specific command failed"); + + if (puk_buff_len == 16) { + rv = cosm_update_pukfile (card, profile, puk_buff, puk_buff_len); + SC_TEST_RET(card->ctx, rv, "Failed to update pukfile"); + } if (puk_buff) free(puk_buff); @@ -288,46 +436,53 @@ static int cosm_create_reference_data(struct sc_profile *profile, sc_card_t *car /* * Update PIN */ -static int cosm_update_pin(struct sc_profile *profile, sc_card_t *card, - struct sc_pkcs15_pin_info *pinfo, const u8 *pin, size_t pin_len, - const u8 *puk, size_t puk_len ) +static int +cosm_update_pin(struct sc_profile *profile, struct sc_card *card, + struct sc_pkcs15_pin_info *pinfo, const unsigned char *pin, size_t pin_len, + const unsigned char *puk, size_t puk_len ) { - int rv; - int tries_left = -1; + int rv, tries_left = -1; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "ref %i; flags %X\n", pinfo->reference, pinfo->flags); if (pinfo->flags & SC_PKCS15_PIN_FLAG_SO_PIN) { - sc_debug(card->ctx,"Pin references should be only in the profile" - "and in the card-oberthur.\n"); if (pinfo->reference != 4) - return SC_ERROR_INVALID_PIN_REFERENCE; + SC_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "cosm_update_pin() invalid SOPIN reference"); rv = sc_change_reference_data(card, SC_AC_CHV, pinfo->reference, puk, puk_len, pin, pin_len, &tries_left); - sc_debug(card->ctx, "return value %X; tries left %i\n", rv, tries_left); - if (tries_left != -1) - sc_debug(card->ctx, "Failed to change reference data for soPin: rv %X", rv); + SC_TEST_RET(card->ctx, rv, "cosm_update_pin() failed to change SOPIN"); + if (tries_left != -1) + SC_TEST_RET(card->ctx, SC_ERROR_INTERNAL, "cosm_update_pin() failed to change SOPIN"); } else { rv = cosm_create_reference_data(profile, card, pinfo, pin, pin_len, puk, puk_len); + SC_TEST_RET(card->ctx, rv, "cosm_update_pin() failed to change PIN"); + + rv = cosm_write_tokeninfo(card, profile, NULL, + SC_PKCS15_CARD_FLAG_TOKEN_INITIALIZED + | SC_PKCS15_CARD_FLAG_PRN_GENERATION + | SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED + | SC_PKCS15_CARD_FLAG_USER_PIN_INITIALIZED); + SC_TEST_RET(card->ctx, rv, "cosm_update_pin() failed to update tokeninfo"); } SC_FUNC_RETURN(card->ctx, 1, rv); } + static int -cosm_select_pin_reference(sc_profile_t *profile, sc_card_t *card, - sc_pkcs15_pin_info_t *pin_info) +cosm_select_pin_reference(struct sc_profile *profile, struct sc_card *card, + struct sc_pkcs15_pin_info *pin_info) { - sc_file_t *pinfile; + struct sc_file *pinfile; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "ref %i; flags %X\n", pin_info->reference, pin_info->flags); - if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0) { + if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0) { sc_debug(card->ctx, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF"); return SC_ERROR_INCONSISTENT_PROFILE; } @@ -337,37 +492,36 @@ cosm_select_pin_reference(sc_profile_t *profile, sc_card_t *card, if (!pin_info->reference) { if (pin_info->flags & SC_PKCS15_PIN_FLAG_SO_PIN) - pin_info->reference = 4; + pin_info->reference = 4; else - pin_info->reference = 1; + pin_info->reference = 1; } - if (pin_info->reference < 0 || pin_info->reference > 4) + if (pin_info->reference < 0 || pin_info->reference > 4) return SC_ERROR_INVALID_PIN_REFERENCE; SC_FUNC_RETURN(card->ctx, 1, SC_SUCCESS); } + /* * Store a PIN */ static int -cosm_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df, - sc_pkcs15_object_t *pin_obj, +cosm_create_pin(struct sc_profile *profile, struct sc_card *card, struct sc_file *df, + struct sc_pkcs15_object *pin_obj, const unsigned char *pin, size_t pin_len, const unsigned char *puk, size_t puk_len) { - sc_pkcs15_pin_info_t *pinfo = (sc_pkcs15_pin_info_t *) pin_obj->data; - sc_file_t *pinfile; + struct sc_pkcs15_pin_info *pinfo = (struct sc_pkcs15_pin_info *) pin_obj->data; + struct sc_file *pinfile; int rv = 0, type; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "ref %i; flags %X\n", pinfo->reference, pinfo->flags); - if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0) { - sc_debug(card->ctx, "Profile doesn't define \"%s\"", COSM_TITLE "-AppDF"); - return SC_ERROR_INCONSISTENT_PROFILE; - } - + if (sc_profile_get_file(profile, COSM_TITLE "-AppDF", &pinfile) < 0) + SC_TEST_RET(card->ctx, SC_ERROR_INCONSISTENT_PROFILE, "\""COSM_TITLE"-AppDF\" not defined"); + pinfo->path = pinfile->path; sc_file_free(pinfile); @@ -375,23 +529,20 @@ cosm_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df, type = SC_PKCS15INIT_SO_PIN; if (pinfo->reference != 4) - return SC_ERROR_INVALID_ARGUMENTS; + SC_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid SOPIN reference"); } else { type = SC_PKCS15INIT_USER_PIN; if (pinfo->reference !=1 && pinfo->reference != 2) - return SC_ERROR_INVALID_PIN_REFERENCE; + SC_TEST_RET(card->ctx, SC_ERROR_INVALID_PIN_REFERENCE, "Invalid PIN reference"); } if (pin && pin_len) { - rv = cosm_update_pin(profile, card, pinfo, pin, pin_len, puk, puk_len); + rv = cosm_update_pin(profile, card, pinfo, pin, pin_len, puk, puk_len); + SC_TEST_RET(card->ctx, rv, "Update PIN failed"); } - else { - sc_debug(card->ctx, "User PIN not updated"); - } - sc_debug(card->ctx, "return %i\n", rv); - + sc_keycache_set_pin_name(&pinfo->path, pinfo->reference, type); pinfo->flags &= ~SC_PKCS15_PIN_FLAG_LOCAL; @@ -403,15 +554,15 @@ cosm_create_pin(sc_profile_t *profile, sc_card_t *card, sc_file_t *df, * Allocate a file */ static int -cosm_new_file(struct sc_profile *profile, sc_card_t *card, - unsigned int type, unsigned int num, sc_file_t **out) +cosm_new_file(struct sc_profile *profile, struct sc_card *card, + unsigned int type, unsigned int num, struct sc_file **out) { struct sc_file *file; const char *_template = NULL, *desc = NULL; unsigned int structure = 0xFFFFFFFF; SC_FUNC_CALLED(card->ctx, 1); - sc_debug(card->ctx, "type %X; num %i\n",type, num); + sc_debug(card->ctx, "cosm_new_file() type %X; num %i\n",type, num); while (1) { switch (type) { case SC_PKCS15_TYPE_PRKEY_RSA: @@ -457,20 +608,20 @@ cosm_new_file(struct sc_profile *profile, sc_card_t *card, type &= SC_PKCS15_TYPE_CLASS_MASK; } - sc_debug(card->ctx, "template %s; num %i\n",_template, num); + sc_debug(card->ctx, "cosm_new_file() template %s; num %i\n",_template, num); if (sc_profile_get_file(profile, _template, &file) < 0) { sc_debug(card->ctx, "Profile doesn't define %s template '%s'\n", desc, _template); - return SC_ERROR_NOT_SUPPORTED; + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } - + file->id |= (num & 0xFF); file->path.value[file->path.len-1] |= (num & 0xFF); if (file->type == SC_FILE_TYPE_INTERNAL_EF) { file->ef_structure = structure; } - sc_debug(card->ctx, "file size %i; ef type %i/%i; id %04X\n",file->size, + sc_debug(card->ctx, "cosm_new_file() file size %i; ef type %i/%i; id %04X\n",file->size, file->type, file->ef_structure, file->id); *out = file; @@ -482,9 +633,9 @@ cosm_new_file(struct sc_profile *profile, sc_card_t *card, * RSA key generation */ static int -cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card, +cosm_old_generate_key(struct sc_profile *profile, struct sc_card *card, unsigned int idx, unsigned int keybits, - sc_pkcs15_pubkey_t *pubkey, + struct sc_pkcs15_pubkey *pubkey, struct sc_pkcs15_prkey_info *info) { struct sc_cardctl_oberthur_genkey_info args; @@ -493,45 +644,37 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card, int rv; SC_FUNC_CALLED(card->ctx, 1); - sc_debug(card->ctx, "index %i; nn %i\n", idx, keybits); + sc_debug(card->ctx, "cosm_generate_key() index %i; nn %i\n", idx, keybits); if (keybits < 512 || keybits > 2048 || (keybits%0x20)) { sc_debug(card->ctx, "Unsupported key size %u\n", keybits); - return SC_ERROR_INVALID_ARGUMENTS; + SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Unsupported key size"); } /* Get private key file from profile. */ - if ((rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, - &prkf)) < 0) - goto failed; - sc_debug(card->ctx, "prv ef type 0x%X\n",prkf->ef_structure); + rv = cosm_new_file(profile, card, SC_PKCS15_TYPE_PRKEY_RSA, idx, &prkf); + SC_TEST_RET(card->ctx, rv, "cosm_generate_key() cannot allocate new file SC_PKCS15_TYPE_PRKEY_RSA"); prkf->size = keybits; /* Access condition of private object DF. */ path = prkf->path; path.len -= 2; - rv = sc_select_file(card, &path, &tmpf); - SC_TEST_RET(card->ctx, rv, "Generate RSA: no private object DF"); + rv = sc_select_file(card, &path, &tmpf); + SC_TEST_RET(card->ctx, rv, "cosm_generate_key() no private object DF"); rv = sc_pkcs15init_authenticate(profile, card, tmpf, SC_AC_OP_CRYPTO); - sc_debug(card->ctx, "rv %i\n",rv); - if (rv < 0) - goto failed; + SC_TEST_RET(card->ctx, rv, "cosm_generate_key() pkcs15init_authenticate(SC_AC_OP_CRYPTO) failed"); rv = sc_pkcs15init_authenticate(profile, card, tmpf, SC_AC_OP_CREATE); - sc_debug(card->ctx, "rv %i\n",rv); - if (rv < 0) - goto failed; + SC_TEST_RET(card->ctx, rv, "cosm_generate_key() pkcs15init_authenticate(SC_AC_OP_CREATE) failed"); sc_file_free(tmpf); /* In the private key DF create the temporary public RSA file. */ - sc_debug(card->ctx, "ready to create public key\n"); + sc_debug(card->ctx, "cosm_generate_key() ready to create temporary public key\n"); sc_file_dup(&tmpf, prkf); - if (tmpf == NULL) { - rv = SC_ERROR_OUT_OF_MEMORY; - goto failed; - } + if (!tmpf) + SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot duplicate private key file"); tmpf->type = SC_FILE_TYPE_INTERNAL_EF; tmpf->ef_structure = SC_CARDCTL_OBERTHUR_KEY_RSA_PUBLIC; tmpf->id = 0x1012; @@ -539,18 +682,10 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card, tmpf->path.value[tmpf->path.len - 1] = 0x12; rv = sc_pkcs15init_create_file(profile, card, prkf); - sc_debug(card->ctx, "rv %i\n",rv); - if (rv) { - sc_debug(card->ctx, "prkf create file failed\n"); - goto failed; - } + SC_TEST_RET(card->ctx, rv, "cosm_generate_key() failed to create private key EF"); rv = sc_pkcs15init_create_file(profile, card, tmpf); - sc_debug(card->ctx, "rv %i\n",rv); - if (rv) { - sc_debug(card->ctx, "pubf create failed\n"); - goto failed; - } + SC_TEST_RET(card->ctx, rv, "cosm_generate_key() failed to create temporary public key EF"); memset(&args, 0, sizeof(args)); args.id_prv = prkf->id; @@ -559,49 +694,37 @@ cosm_old_generate_key(struct sc_profile *profile, sc_card_t *card, args.key_bits = keybits; args.pubkey_len = keybits/8; args.pubkey = (unsigned char *) malloc(keybits/8); - if (!args.pubkey) { - rv = SC_ERROR_OUT_OF_MEMORY; - goto failed; - } + if (!args.pubkey) + SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate pubkey"); rv = sc_card_ctl(card, SC_CARDCTL_OBERTHUR_GENERATE_KEY, &args); - if (rv < 0) - goto failed; + SC_TEST_RET(card->ctx, rv, "cosm_generate_key() CARDCTL_OBERTHUR_GENERATE_KEY failed"); /* extract public key */ pubkey->algorithm = SC_ALGORITHM_RSA; pubkey->u.rsa.modulus.len = keybits / 8; - pubkey->u.rsa.modulus.data = (u8 *) malloc(keybits / 8); - if (!pubkey->u.rsa.modulus.data) { - rv = SC_ERROR_MEMORY_FAILURE; - goto failed; - } + pubkey->u.rsa.modulus.data = (unsigned char *) malloc(keybits / 8); + if (!pubkey->u.rsa.modulus.data) + SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate modulus buf"); /* FIXME and if the exponent length is not 3? */ pubkey->u.rsa.exponent.len = 3; - pubkey->u.rsa.exponent.data = (u8 *) malloc(3); - if (!pubkey->u.rsa.exponent.data) { - rv = SC_ERROR_MEMORY_FAILURE; - goto failed; - } + pubkey->u.rsa.exponent.data = (unsigned char *) malloc(3); + if (!pubkey->u.rsa.exponent.data) + SC_TEST_RET(card->ctx, SC_ERROR_OUT_OF_MEMORY, "cosm_generate_key() cannot allocate exponent buf"); memcpy(pubkey->u.rsa.exponent.data, "\x01\x00\x01", 3); memcpy(pubkey->u.rsa.modulus.data, args.pubkey, args.pubkey_len); info->key_reference = 1; info->path = prkf->path; - if (rv) { - sc_debug(card->ctx, "rv %i\n", rv); - goto failed; - } + sc_debug(card->ctx, "cosm_generate_key() now delete temporary public key\n"); + rv = cosm_delete_file(card, profile, tmpf); - sc_debug(card->ctx, "delete temporary public key\n"); - if ((rv = cosm_delete_file(card, profile, tmpf))) - goto failed; - -failed: - if (tmpf) sc_file_free(tmpf); - if (prkf) sc_file_free(prkf); + if (tmpf) + sc_file_free(tmpf); + if (prkf) + sc_file_free(prkf); SC_FUNC_RETURN(card->ctx, 1, rv); } @@ -611,7 +734,7 @@ failed: * Store a private key */ static int -cosm_new_key(struct sc_profile *profile, sc_card_t *card, +cosm_new_key(struct sc_profile *profile, struct sc_card *card, struct sc_pkcs15_prkey *key, unsigned int idx, struct sc_pkcs15_prkey_info *info) { @@ -652,7 +775,8 @@ cosm_new_key(struct sc_profile *profile, sc_card_t *card, rv = sc_pkcs15init_authenticate(profile, card, prvfile, SC_AC_OP_UPDATE); SC_TEST_RET(card->ctx, rv, "Update RSA: no authorisation"); -#ifdef ENABLE_OPENSSL +#ifdef ENABLE_OPENSSL + /* Mozilla style ID */ if (!info->id.len) { SHA1(rsa->modulus.data, rsa->modulus.len, info->id.value); info->id.len = SHA_DIGEST_LENGTH; diff --git a/src/pkcs15init/pkcs15.profile b/src/pkcs15init/pkcs15.profile index da4c6e1d..9b9a7202 100644 --- a/src/pkcs15init/pkcs15.profile +++ b/src/pkcs15init/pkcs15.profile @@ -21,7 +21,13 @@ pkcs15 { # Put the DF length into the ODF file? encode-df-length = no; # Have a lastUpdate field in the EF(TokenInfo)? - do-last-update = yes; + do-last-update = yes; + # Method to calculate ID of the crypto objects + # mozilla: SHA1(modulus) for RSA, SHA1(pub) for DSA + # rfc2459: SHA1(SequenceASN1 of public key components as ASN1 integers) + # native: 'E' + number_of_present_objects_of_the_same_type + # default value: 'native' + # pkcs15-id-style = mozilla; } # Default settings. diff --git a/src/pkcs15init/profile.c b/src/pkcs15init/profile.c index be7bbfc0..f1067303 100644 --- a/src/pkcs15init/profile.c +++ b/src/pkcs15init/profile.c @@ -104,7 +104,10 @@ static struct map fileOpNames[] = { { "UPDATE", SC_AC_OP_UPDATE }, { "WRITE", SC_AC_OP_WRITE }, { "ERASE", SC_AC_OP_ERASE }, - { "CRYPTO", SC_AC_OP_CRYPTO }, + { "CRYPTO", SC_AC_OP_CRYPTO }, + { "PIN-DEFINE", SC_AC_OP_PIN_DEFINE }, + { "PIN-CHANGE", SC_AC_OP_PIN_CHANGE }, + { "PIN-RESET", SC_AC_OP_PIN_RESET }, { NULL, 0 } }; static struct map fileTypeNames[] = { @@ -169,6 +172,12 @@ static struct map pinFlagNames[] = { { "exchangeRefData", 0x0800 }, { NULL, 0 } }; +static struct map idStyleNames[] = { + { "native", SC_PKCS15INIT_ID_STYLE_NATIVE }, + { "mozilla", SC_PKCS15INIT_ID_STYLE_MOZILLA }, + { "rfc2459", SC_PKCS15INIT_ID_STYLE_RFC2459 }, + { NULL, 0 } +}; static struct { const char * name; struct map * addr; @@ -280,6 +289,7 @@ sc_profile_new(void) pro->pin_minlen = 4; pro->pin_maxlen = 8; pro->keep_public_key = 1; + pro->id_style = SC_PKCS15INIT_ID_STYLE_NATIVE; return pro; } @@ -780,6 +790,12 @@ do_encode_update_field(struct state *cur, int argc, char **argv) return get_bool(cur, argv[0], &cur->profile->pkcs15.do_last_update); } +static int +do_pkcs15_id_style(struct state *cur, int argc, char **argv) +{ + return map_str2int(cur, argv[0], &cur->profile->id_style, idStyleNames); +} + /* * Process an option block */ @@ -1525,6 +1541,7 @@ static struct command p15_commands[] = { { "direct-certificates", 1, 1, do_direct_certificates }, { "encode-df-length", 1, 1, do_encode_df_length }, { "do-last-update", 1, 1, do_encode_update_field }, + { "pkcs15-id-style", 1, 1, do_pkcs15_id_style }, { NULL, 0, 0, NULL } }; diff --git a/src/pkcs15init/profile.h b/src/pkcs15init/profile.h index f4e62589..fdabe3ce 100644 --- a/src/pkcs15init/profile.h +++ b/src/pkcs15init/profile.h @@ -120,6 +120,9 @@ struct sc_profile { * needs to be updated (in other words: if the card content * has been changed) */ int dirty; + + /* PKCS15 object ID style */ + unsigned int id_style; }; struct sc_profile *sc_profile_new(void); diff --git a/src/tools/pkcs15-tool.c b/src/tools/pkcs15-tool.c index 431c8d50..5800c3a1 100644 --- a/src/tools/pkcs15-tool.c +++ b/src/tools/pkcs15-tool.c @@ -68,7 +68,7 @@ enum { #endif OPT_PIN, OPT_NEWPIN, - OPT_PUK, + OPT_PUK }; #define NELEMENTS(x) (sizeof(x)/sizeof((x)[0])) @@ -119,7 +119,9 @@ static const char *option_help[] = { "Lists private keys", "Lists public keys", "Reads public key with ID ", +#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H)) "Reads public key with ID , outputs ssh format", +#endif "Test if the card needs a security update", "Update the card with a security update", "Uses reader number ", @@ -402,6 +404,7 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) { unsigned int i; struct sc_pkcs15_prkey_info *prkey = (struct sc_pkcs15_prkey_info *) obj->data; + const char *types[] = { "", "RSA", "DSA", "GOSTR3410" }; const char *usages[] = { "encrypt", "decrypt", "sign", "signRecover", "wrap", "unwrap", "verify", "verifyRecover", @@ -414,13 +417,13 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) }; const unsigned int af_count = NELEMENTS(access_flags); - printf("Private RSA Key [%s]\n", obj->label); + printf("Private %s Key [%s]\n", types[3 & obj->type], obj->label); printf("\tCom. Flags : %X\n", obj->flags); printf("\tUsage : [0x%X]", prkey->usage); for (i = 0; i < usage_count; i++) - if (prkey->usage & (1 << i)) { - printf(", %s", usages[i]); - } + if (prkey->usage & (1 << i)) { + printf(", %s", usages[i]); + } printf("\n"); printf("\tAccess Flags: [0x%X]", prkey->access_flags); for (i = 0; i < af_count; i++) @@ -440,9 +443,9 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj) static int list_private_keys(void) { int r, i; - struct sc_pkcs15_object *objs[32]; - - r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY_RSA, objs, 32); + struct sc_pkcs15_object *objs[32]; + + r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, objs, 32); if (r < 0) { fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r)); return 1; @@ -460,6 +463,7 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj) { unsigned int i; const struct sc_pkcs15_pubkey_info *pubkey = (const struct sc_pkcs15_pubkey_info *) obj->data; + const char *types[] = { "", "RSA", "DSA", "GOSTR3410" }; const char *usages[] = { "encrypt", "decrypt", "sign", "signRecover", "wrap", "unwrap", "verify", "verifyRecover", @@ -472,7 +476,7 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj) }; const unsigned int af_count = NELEMENTS(access_flags); - printf("Public RSA Key [%s]\n", obj->label); + printf("Public %s Key [%s]\n", types[3 & obj->type], obj->label); printf("\tCom. Flags : %X\n", obj->flags); printf("\tUsage : [0x%X]", pubkey->usage); for (i = 0; i < usage_count; i++) @@ -498,8 +502,8 @@ static int list_public_keys(void) { int r, i; struct sc_pkcs15_object *objs[32]; - - r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY_RSA, objs, 32); + + r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PUBKEY, objs, 32); if (r < 0) { fprintf(stderr, "Public key enumeration failed: %s\n", sc_strerror(r)); return 1; @@ -906,7 +910,7 @@ static void print_pin_info(const struct sc_pkcs15_object *obj) (unsigned long)pin->stored_length); printf("\tPad char : 0x%02X\n", pin->pad_char); printf("\tReference : %d\n", pin->reference); - if (pin->type >= 0 && pin->type < sizeof(pin_types)/sizeof(pin_types[0])) + if (pin->type < sizeof(pin_types)/sizeof(pin_types[0])) printf("\tType : %s\n", pin_types[pin->type]); else printf("\tType : [encoding %d]\n", pin->type); @@ -1146,7 +1150,7 @@ static int learn_card(void) return 1; } cert_count = r; - r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY_RSA, NULL, 0); + r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0); if (r < 0) { fprintf(stderr, "Private key enumeration failed: %s\n", sc_strerror(r)); return 1; @@ -1241,7 +1245,7 @@ static int test_update(sc_card_t *in_card) } { - int i=0; + size_t i=0; while(i < rbuf[1]) { if (rbuf[2+i] == 0x86) { /* found our buffer */ break; From 684e9b20baa4a9094872b47f5a7c4c70e8e6fae1 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:10:44 +0000 Subject: [PATCH 40/57] Convert newlines to unix style, remove compiler warnings. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3826 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-myeid.c | 146 ++++++++++++++++++------------------- 1 file changed, 73 insertions(+), 73 deletions(-) diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 0238af4d..26459a42 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -25,19 +25,19 @@ #include #include -#define LOAD_KEY_MODULUS 0x80 -#define LOAD_KEY_PUBLIC_EXPONENT 0x81 -#define LOAD_KEY_PRIME_P 0x83 -#define LOAD_KEY_PRIME_Q 0x84 -#define LOAD_KEY_DP1 0x85 -#define LOAD_KEY_DQ1 0x86 -#define LOAD_KEY_INVQ 0x87 +#define LOAD_KEY_MODULUS 0x80 +#define LOAD_KEY_PUBLIC_EXPONENT 0x81 +#define LOAD_KEY_PRIME_P 0x83 +#define LOAD_KEY_PRIME_Q 0x84 +#define LOAD_KEY_DP1 0x85 +#define LOAD_KEY_DQ1 0x86 +#define LOAD_KEY_INVQ 0x87 static struct sc_card_operations myeid_ops; static struct sc_card_driver myeid_drv = { "MyEID cards with PKCS#15 applet", "myeid", - &myeid_ops + &myeid_ops }; static const char *myeid_atrs[] = { @@ -89,7 +89,7 @@ static int myeid_init(struct sc_card *card) /* State that we have an RNG */ card->caps |= SC_CARD_CAP_RNG; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); return 0; } @@ -104,9 +104,9 @@ static int acl_to_byte(const struct sc_acl_entry *e) case SC_AC_TERM: case SC_AC_AUT: if (e->key_ref == SC_AC_KEY_REF_NONE) - return 0x00; + return 0x00; if (e->key_ref < 1 || e->key_ref > 14) - return 0x00; + return 0x00; return e->key_ref; case SC_AC_NEVER: return 0x0F; @@ -179,26 +179,26 @@ static int myeid_select_file(struct sc_card *card, const struct sc_path *in_path struct sc_file **file) { int r; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); r = iso_ops->select_file(card, in_path, file); - if (r == 0 && file != NULL) { + if (r == 0 && file != NULL) { parse_sec_attr(*file, (*file)->sec_attr, (*file)->sec_attr_len); } - SC_FUNC_RETURN(card->ctx, 1, r); + SC_FUNC_RETURN(card->ctx, 1, r); } static int myeid_read_binary(struct sc_card *card, unsigned int idx, u8 * buf, size_t count, unsigned long flags) { - SC_FUNC_CALLED(card->ctx, 1); - SC_FUNC_RETURN(card->ctx, 1, iso_ops->read_binary(card, idx, buf, count, flags)); + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, iso_ops->read_binary(card, idx, buf, count, flags)); } static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen) { struct sc_apdu apdu; - int r,i; + int r; SC_FUNC_CALLED(card->ctx, 1); @@ -222,10 +222,10 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file, const u8 *tag = NULL; int r ; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); r = iso_ops->process_fci(card, file, buf, buflen); if (r < 0) - SC_FUNC_RETURN(card->ctx, 1, r); + SC_FUNC_RETURN(card->ctx, 1, r); if(file->type == SC_FILE_EF_UNKNOWN) { @@ -241,17 +241,17 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file, file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]); } - SC_FUNC_RETURN(card->ctx, 1, 0); + SC_FUNC_RETURN(card->ctx, 1, 0); } static int encode_file_structure(sc_card_t *card, const sc_file_t *file, u8 *out, size_t *outlen) { - const sc_acl_entry_t *read, *update, *delete; + const sc_acl_entry_t *read, *update, *delete; u8 buf[40]; int i; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); /* PrivateKey * 0E0000019 6217 81020400 820111 83024B01 8603000000 85028000 8A0100 RESULT 6984 * 6217 81020400 820111 83024B01 8603000000 85021000 8A0100 */ @@ -290,38 +290,38 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, buf[17] = file->sec_attr[2]; sc_debug(card->ctx, "id (%X), sec_attr %X %X %X\n", file->id, - file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]); + file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]); } else { delete = sc_file_get_acl_entry(file, SC_AC_OP_DELETE); - switch (file->type) { - case SC_FILE_TYPE_WORKING_EF: + switch (file->type) { + case SC_FILE_TYPE_WORKING_EF: read = sc_file_get_acl_entry(file, SC_AC_OP_READ); update = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE); buf[15] = (acl_to_byte(read) << 4) | acl_to_byte(update); - buf[16] = (acl_to_byte(delete)<< 4) | 0x0F; - break; - case SC_FILE_TYPE_INTERNAL_EF: + buf[16] = (acl_to_byte(delete)<< 4) | 0x0F; + break; + case SC_FILE_TYPE_INTERNAL_EF: read = sc_file_get_acl_entry(file, SC_AC_OP_CRYPTO); update = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE); buf[15] = (acl_to_byte(read) << 4) | acl_to_byte(update); - buf[16] = (acl_to_byte(delete)<< 4) | 0x0F; - break; - case SC_FILE_TYPE_DF: + buf[16] = (acl_to_byte(delete)<< 4) | 0x0F; + break; + case SC_FILE_TYPE_DF: update = sc_file_get_acl_entry(file, SC_AC_OP_CREATE); buf[15] = (acl_to_byte(update) << 4) | acl_to_byte(update); - buf[16] = (acl_to_byte(delete) << 4) | 0x0F; - break; - default: - break; + buf[16] = (acl_to_byte(delete) << 4) | 0x0F; + break; + default: + break; } } @@ -352,10 +352,10 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, { buf[25] = 0x84; buf[26] = (u8)file->namelen; - + for(i=0;i < (int)file->namelen;i++) buf[i + 26] = file->name[i]; - + buf[1] = 0x19 + file->namelen + 2; } break; @@ -367,7 +367,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file, *outlen = buf[1]+2; memcpy(out, buf, *outlen); - SC_FUNC_RETURN(card->ctx, 1, 0); + SC_FUNC_RETURN(card->ctx, 1, 0); } static int myeid_create_file(struct sc_card *card, struct sc_file *file) @@ -378,7 +378,7 @@ static int myeid_create_file(struct sc_card *card, struct sc_file *file) int r; SC_FUNC_CALLED(card->ctx, 1); - + r = encode_file_structure(card, file, sbuf, &buflen); if (r) SC_FUNC_RETURN(card->ctx, 1, r); @@ -392,9 +392,9 @@ static int myeid_create_file(struct sc_card *card, struct sc_file *file) SC_TEST_RET(card->ctx, r, "APDU transmit failed"); if (apdu.sw1 == 0x6A && apdu.sw2 == 0x89) SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_FILE_ALREADY_EXISTS); - + r = sc_check_sw(card, apdu.sw1, apdu.sw2); - SC_TEST_RET(card->ctx, r, "Card returned error"); + SC_FUNC_RETURN(card->ctx, r, "Card returned error"); } /* no record oriented file services */ @@ -402,37 +402,37 @@ static int myeid_read_record_unsupp(struct sc_card *card, unsigned int rec_nr, u8 *buf, size_t count, unsigned long flags) { SC_FUNC_CALLED(card->ctx, 1); - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } static int myeid_wrupd_record_unsupp(struct sc_card *card, unsigned int rec_nr, const u8 *buf, size_t count, unsigned long flags) { SC_FUNC_CALLED(card->ctx, 1); - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } static int myeid_append_record_unsupp(struct sc_card *card, const u8 *buf, size_t count, unsigned long flags) { - SC_FUNC_CALLED(card->ctx, 1); - SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED); } static int myeid_write_binary(struct sc_card *card, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) { - SC_FUNC_CALLED(card->ctx, 1); - SC_FUNC_RETURN(card->ctx, 1, iso_ops->write_binary(card, idx, buf, count, flags)); + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, iso_ops->write_binary(card, idx, buf, count, flags)); } static int myeid_update_binary(struct sc_card *card, unsigned int idx, const u8 *buf, size_t count, unsigned long flags) { - SC_FUNC_CALLED(card->ctx, 1); - SC_FUNC_RETURN(card->ctx, 1, iso_ops->update_binary(card, idx, buf, count, flags)); + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, iso_ops->update_binary(card, idx, buf, count, flags)); } static int myeid_delete_file(struct sc_card *card, const struct sc_path *path) @@ -455,7 +455,7 @@ static int myeid_delete_file(struct sc_card *card, const struct sc_path *path) r = sc_transmit_apdu(card, &apdu); SC_TEST_RET(card->ctx, r, "APDU transmit failed"); - SC_FUNC_RETURN(card->ctx, 1, sc_check_sw(card, apdu.sw1, apdu.sw2)); + SC_FUNC_RETURN(card->ctx, 1, sc_check_sw(card, apdu.sw1, apdu.sw2)); } static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, @@ -481,7 +481,7 @@ static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, } SC_FUNC_RETURN(card->ctx, 1, iso_ops->pin_cmd(card, data, tries_left)); -} +} static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env, int se_num) @@ -492,7 +492,7 @@ static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env int r, locked = 0; assert(card != NULL && env != NULL); - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) { @@ -575,14 +575,14 @@ static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env err: if (locked) sc_unlock(card); - SC_FUNC_RETURN(card->ctx, 1, r); + SC_FUNC_RETURN(card->ctx, 1, r); } static int myeid_set_security_env(struct sc_card *card, const struct sc_security_env *env, int se_num) { SC_FUNC_CALLED(card->ctx, 1); - + if (env->flags & SC_SEC_ENV_ALG_PRESENT) { sc_security_env_t tmp; @@ -617,7 +617,7 @@ static int myeid_compute_signature(struct sc_card *card, const u8 * data, u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; SC_FUNC_CALLED(card->ctx, 1); - + assert(card != NULL && data != NULL && out != NULL); if (datalen > 256) SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS); @@ -667,7 +667,7 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram, u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; SC_FUNC_CALLED(card->ctx, 1); - + assert(card != NULL && crgram != NULL && out != NULL); SC_FUNC_CALLED(card->ctx, 2); if (crgram_len > 256) @@ -810,7 +810,7 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len) u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; int r, len; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); len = 0; if(value_len == 0 || value == NULL) return 0; @@ -881,9 +881,9 @@ static int myeid_generate_store_key(struct sc_card *card, { struct sc_apdu apdu; u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; - int r=0,len; + int r=0,len; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); /* Setup key-generation paramters */ if (data->op_type == OP_TYPE_GENERATE) { @@ -926,10 +926,10 @@ static int myeid_generate_store_key(struct sc_card *card, data->mod, data->mod_len)) >= 0 && (r=myeid_loadkey(card, LOAD_KEY_PUBLIC_EXPONENT, data->pubexp, data->pubexp_len)) >= 0) - SC_FUNC_RETURN(card->ctx, 1, r); + SC_FUNC_RETURN(card->ctx, 1, r); } - SC_FUNC_RETURN(card->ctx, 1, r); + SC_FUNC_RETURN(card->ctx, 1, r); } static int myeid_activate_card(struct sc_card *card) @@ -938,7 +938,7 @@ static int myeid_activate_card(struct sc_card *card) u8 sbuf[] ="\xA0\x00\x00\x00\x63\x50\x4B\x43\x53\x2D\x31\x35"; sc_apdu_t apdu; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x44, 0x04, 0x00); apdu.cla = 0x00; apdu.data = sbuf; @@ -960,7 +960,7 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) sc_apdu_t apdu; u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0xA0); apdu.resp = rbuf; apdu.resplen = sizeof(rbuf); @@ -985,27 +985,27 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial) /* copy and return serial number */ memcpy(serial, &card->serialnr, sizeof(*serial)); - SC_FUNC_RETURN(card->ctx, 1, r); + SC_FUNC_RETURN(card->ctx, 1, r); } static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) { int r = SC_ERROR_NOT_SUPPORTED; SC_FUNC_CALLED(card->ctx, 1); - + switch(cmd) { case SC_CARDCTL_MYEID_PUTDATA: r = myeid_putdata(card, (struct sc_cardctl_myeid_data_obj*) ptr); - break; + break; case SC_CARDCTL_MYEID_GETDATA: r = myeid_getdata(card, (struct sc_cardctl_myeid_data_obj*) ptr); - break; + break; case SC_CARDCTL_MYEID_GENERATE_KEY: r = myeid_generate_store_key(card, (struct sc_cardctl_myeid_gen_store_key_info *) ptr); - break; + break; case SC_CARDCTL_MYEID_ACTIVATE_CARD: r = myeid_activate_card(card); break; @@ -1014,9 +1014,9 @@ static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) break; case SC_CARDCTL_LIFECYCLE_SET: case SC_CARDCTL_LIFECYCLE_GET: - break; + break; } - SC_FUNC_RETURN(card->ctx, 1, r); + SC_FUNC_RETURN(card->ctx, 1, r); } /* "The PINs are "global" in a PKCS#15 sense, meaning that they remain valid @@ -1026,8 +1026,8 @@ static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr) */ static int myeid_logout(struct sc_card *card) { - SC_FUNC_CALLED(card->ctx, 1); - SC_FUNC_RETURN(card->ctx, 1, 0); + SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_RETURN(card->ctx, 1, 0); } static struct sc_card_driver * sc_get_driver(void) @@ -1057,7 +1057,7 @@ static struct sc_card_driver * sc_get_driver(void) myeid_ops.logout = myeid_logout; myeid_ops.process_fci = myeid_process_fci; myeid_ops.card_ctl = myeid_card_ctl; - myeid_ops.pin_cmd = myeid_pin_cmd; + myeid_ops.pin_cmd = myeid_pin_cmd; return &myeid_drv; } From 1a6f8b7468a4d5f0576f76ee67d19f46e4273cde Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:12:14 +0000 Subject: [PATCH 41/57] Remove unused variables git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3827 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-ias.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libopensc/card-ias.c b/src/libopensc/card-ias.c index 034d92d0..2fadbe57 100644 --- a/src/libopensc/card-ias.c +++ b/src/libopensc/card-ias.c @@ -355,7 +355,7 @@ static int ias_select_file(sc_card_t *card, const sc_path_t *in_path, u8 buf[SC_MAX_APDU_BUFFER_SIZE]; u8 pathbuf[SC_MAX_PATH_SIZE], *path; sc_context_t *ctx; - sc_apdu_t apdu, rapdu; + sc_apdu_t apdu; sc_file_t *file; r = pathlen = stripped_len = offset = 0; @@ -454,7 +454,6 @@ static int ias_select_file(sc_card_t *card, const sc_path_t *in_path, if (stripped_len > 0 && apdu.sw1 == 0x6A && apdu.sw2 == 0x82) { sc_file_t *file = NULL; sc_path_t tpath; - int i; /* Restore original path value */ path -= stripped_len; From 17b7e1b0413b8a775fb210eff07d4711749b03b4 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:12:43 +0000 Subject: [PATCH 42/57] Remove unused variables git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3828 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-piv.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libopensc/card-piv.c b/src/libopensc/card-piv.c index 790e2887..32659701 100644 --- a/src/libopensc/card-piv.c +++ b/src/libopensc/card-piv.c @@ -581,7 +581,6 @@ static int piv_find_aid(sc_card_t * card, sc_file_t *aid_file) static int piv_get_data(sc_card_t * card, int enumtag, u8 **buf, size_t *buf_len) { - piv_private_data_t * priv = PIV_DATA(card); u8 *p; int r = 0; u8 tagbuf[8]; From a869431ff66b462413a6c7a06c93eca7adc144f8 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:13:01 +0000 Subject: [PATCH 43/57] Remove unused variables git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3829 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/log.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libopensc/log.c b/src/libopensc/log.c index 350616d4..c0c4633b 100644 --- a/src/libopensc/log.c +++ b/src/libopensc/log.c @@ -58,7 +58,6 @@ void sc_do_log_va(sc_context_t *ctx, int type, const char *file, int line, const { int (*display_fn)(sc_context_t *, const char *); char buf[1836], *p; - const char *tag = ""; int r; size_t left; From 3a3c0b3fe68e8e7fb29bfb179bffe6e32bbddc44 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:13:14 +0000 Subject: [PATCH 44/57] Remove unused variables git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3830 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/p15emu-westcos.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libopensc/p15emu-westcos.c b/src/libopensc/p15emu-westcos.c index d66e5023..44be3df9 100644 --- a/src/libopensc/p15emu-westcos.c +++ b/src/libopensc/p15emu-westcos.c @@ -34,7 +34,6 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card) int modulus_length = 0, usage = 0; char buf[256]; sc_card_t *card = p15card->card; - sc_context_t *ctx = card->ctx; sc_serial_number_t serial; sc_path_t path; sc_file_t *file = NULL; From bb9423c5f990adcffb481375afec2d0e3e93fcc0 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:13:35 +0000 Subject: [PATCH 45/57] Remove unusued variables git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3831 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/pkcs15.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libopensc/pkcs15.c b/src/libopensc/pkcs15.c index b83bae19..93c6588e 100644 --- a/src/libopensc/pkcs15.c +++ b/src/libopensc/pkcs15.c @@ -692,8 +692,8 @@ int sc_pkcs15_bind(sc_card_t *card, { struct sc_pkcs15_card *p15card = NULL; sc_context_t *ctx; - scconf_block *conf_block = NULL, **blocks; - int i, r, emu_first, enable_emu; + scconf_block *conf_block = NULL; + int r, emu_first, enable_emu; assert(sc_card_valid(card) && p15card_out != NULL); ctx = card->ctx; From 48924f32223f9922519662b2957dce546706c585 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:14:10 +0000 Subject: [PATCH 46/57] Remove unused variables git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3832 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/pkcs11/framework-pkcs15.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index 48b3dc77..cd89a795 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -2200,7 +2200,6 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj, { struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj; struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fw_data; - struct pkcs15_slot_data *data = slot_data(ses->slot->fw_data); int rv, flags = 0; sc_debug(context, "Initiating signing operation, mechanism 0x%x.\n", @@ -2292,7 +2291,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj, { struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fw_data; struct pkcs15_prkey_object *prkey; - struct pkcs15_slot_data *data = slot_data(ses->slot->fw_data); u8 decrypted[256]; int buff_too_small, rv, flags = 0; @@ -2578,7 +2576,6 @@ static int pkcs15_dobj_get_value(struct sc_pkcs11_session *session, int rv; struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) session->slot->card->fw_data; - struct pkcs15_slot_data *data = slot_data(session->slot->fw_data); sc_card_t *card = session->slot->card->card; int reader = session->slot->card->reader; @@ -2689,7 +2686,6 @@ static CK_RV pkcs15_dobj_destroy(struct sc_pkcs11_session *session, void *object struct pkcs15_data_object *obj = (struct pkcs15_data_object*) object; struct sc_pkcs11_card *card = session->slot->card; struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) card->fw_data; - struct pkcs15_slot_data *data = slot_data(session->slot->fw_data); struct sc_profile *profile = NULL; int reader = session->slot->card->reader; int rv; From e5b644c2f7a868322f8394c08d81873c6df73859 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:15:00 +0000 Subject: [PATCH 47/57] Remove unused variables git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3833 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/pkcs15init/pkcs15-oberthur.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs15init/pkcs15-oberthur.c b/src/pkcs15init/pkcs15-oberthur.c index bc45bba5..365f8b97 100644 --- a/src/pkcs15init/pkcs15-oberthur.c +++ b/src/pkcs15init/pkcs15-oberthur.c @@ -152,7 +152,7 @@ cosm_update_pukfile (struct sc_card *card, struct sc_profile *profile, { struct sc_pkcs15_pin_info profile_puk; struct sc_file *file = NULL; - int rv, sz, flags = 0; + int rv; unsigned char buffer[16]; SC_FUNC_CALLED(card->ctx, 1); From b34a1a6128b4c6636b6445dcdb515fd87afd7de4 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:19:46 +0000 Subject: [PATCH 48/57] Remove unused variables & fix line endings. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3834 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/pkcs15init/pkcs15-myeid.c | 63 ++++++++++++++++------------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/src/pkcs15init/pkcs15-myeid.c b/src/pkcs15init/pkcs15-myeid.c index cece5444..415ce6bc 100644 --- a/src/pkcs15init/pkcs15-myeid.c +++ b/src/pkcs15init/pkcs15-myeid.c @@ -47,24 +47,27 @@ static int myeid_create_pin_internal(sc_profile_t *, sc_card_t *, static int myeid_puk_retries(sc_profile_t *profile, sc_pkcs15_pin_info_t *pin_info); -static int acl_to_byte(const struct sc_acl_entry *e) -{ - switch (e->method) { - case SC_AC_NONE: - return 0x00; - case SC_AC_CHV: - case SC_AC_TERM: - case SC_AC_AUT: - if (e->key_ref == SC_AC_KEY_REF_NONE) - return 0x00; - if (e->key_ref < 1 || e->key_ref > MYEID_MAX_PINS) - return 0x00; - return e->key_ref; - case SC_AC_NEVER: - return 0x0F; - } - return 0x00; +#if 0 +/* FIXME: Not used, remove */ +static int acl_to_byte(const struct sc_acl_entry *e) +{ + switch (e->method) { + case SC_AC_NONE: + return 0x00; + case SC_AC_CHV: + case SC_AC_TERM: + case SC_AC_AUT: + if (e->key_ref == SC_AC_KEY_REF_NONE) + return 0x00; + if (e->key_ref < 1 || e->key_ref > MYEID_MAX_PINS) + return 0x00; + return e->key_ref; + case SC_AC_NEVER: + return 0x0F; + } + return 0x00; } +#endif /* * Erase the card. @@ -91,11 +94,11 @@ static int myeid_erase_card(sc_profile_t *profile, sc_card_t *card) data[0]= 0xFF; data[1]= 0xFF; - data[2]= 0x11; + data[2]= 0x11; data[3]= 0x3F; data[4]= 0xFF; - data[5]= 0x11; - data[6]= 0xFF; + data[5]= 0x11; + data[6]= 0xFF; data[7]= 0xFF; sc_profile_get_pin_info(profile, SC_PKCS15INIT_USER_PIN, &pin_info); @@ -106,15 +109,15 @@ static int myeid_erase_card(sc_profile_t *profile, sc_card_t *card) data[3] = (sopin_info.reference << 4) | 0x0F; data[5] = data[2]; } - + data_obj.P1 = 0x01; data_obj.P2 = 0xE0; data_obj.Data = data; data_obj.DataLen = 0x08; sc_debug(card->ctx, "so_pin(%d), user pin (%d)\n", - sopin_info.reference, pin_info.reference); - + sopin_info.reference, pin_info.reference); + r = sc_card_ctl(card, SC_CARDCTL_MYEID_PUTDATA, &data_obj); SC_FUNC_RETURN(card->ctx, 1, r); @@ -124,7 +127,6 @@ static int myeid_init_card(sc_profile_t *profile, sc_card_t *card) { struct sc_path path; - sc_file_t *file; int r; SC_FUNC_CALLED(card->ctx, 1); @@ -141,7 +143,6 @@ static int myeid_init_card(sc_profile_t *profile, static int myeid_create_dir(sc_profile_t *profile, sc_card_t *card, sc_file_t *df) { int r=0; - struct sc_file *file; SC_FUNC_CALLED(card->ctx, 1); if (!profile || !card || !df) @@ -163,7 +164,6 @@ static int myeid_create_dir(sc_profile_t *profile, sc_card_t *card, sc_file_t *d static int myeid_select_pin_reference(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_pin_info_t *pin_info) { - sc_pkcs15_pin_info_t pin_info_prof; int type; SC_FUNC_CALLED(card->ctx, 1); @@ -214,7 +214,7 @@ static int myeid_new_file(sc_profile_t *profile, sc_card_t *card, char name[64], *tag; int r; - SC_FUNC_CALLED(card->ctx, 1); + SC_FUNC_CALLED(card->ctx, 1); if (type == SC_PKCS15_TYPE_PRKEY_RSA) tag = "private-key"; else if (type == SC_PKCS15_TYPE_PUBKEY_RSA) @@ -311,10 +311,7 @@ static int myeid_generate_store_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_prkey_info_t *info) { struct sc_cardctl_myeid_gen_store_key_info args; - struct sc_cardctl_myeid_data_obj data_obj; - unsigned char raw_pubkey[256]; int r; - unsigned int mod_len; sc_file_t *prkf = NULL; SC_FUNC_CALLED(card->ctx, 1); @@ -398,15 +395,13 @@ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card, const u8 *puk, size_t puk_len) { u8 data[20]; - int so_pin_ref; int r,type, puk_tries; struct sc_cardctl_myeid_data_obj data_obj; - sc_file_t *pinfile = NULL; SC_FUNC_CALLED(card->ctx, 1); sc_debug(card->ctx, "pin (%d), pin_len (%d), puk_len(%d) \n", pin_info->reference, pin_len, puk_len); - + if (pin_info->reference >= MYEID_MAX_PINS) return SC_ERROR_INVALID_ARGUMENTS; if (pin == NULL || puk == NULL || pin_len < 4 || puk_len < 4) @@ -428,7 +423,7 @@ static int myeid_create_pin_internal(sc_profile_t *profile, sc_card_t *card, memcpy(&data[0], (u8 *)pin, pin_len); /* copy pin*/ memcpy(&data[8], (u8 *)puk, puk_len); /* copy puk */ - data[16] = 0x00; + data[16] = 0x00; data[17] = 0x00; data[18] = 0x00; From bc1d4c4e06e0d7f2eba136d865ea14612427b475 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:21:09 +0000 Subject: [PATCH 49/57] Fix compiler warnings and a typo git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3835 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/tools/cardos-tool.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/tools/cardos-tool.c b/src/tools/cardos-tool.c index b7da9f32..65868c02 100644 --- a/src/tools/cardos-tool.c +++ b/src/tools/cardos-tool.c @@ -372,14 +372,14 @@ static int cardos_sm4h(unsigned char *in, size_t inlen, unsigned char /* using a buffer with an APDU, build an SM 4h APDU for cardos */ int plain_lc; /* data size in orig APDU */ - int mac_input_len, enc_input_len; + unsigned int mac_input_len, enc_input_len; unsigned char *mac_input, *enc_input; DES_key_schedule ks_a, ks_b; DES_cblock des_in,des_out; int i,j; if (keylen != 16) { - printf("key has wrong size, need 16 bytes, got %d. aborting.\n", + printf("key has wrong size, need 16 bytes, got %zd. aborting.\n", keylen); return 0; } @@ -580,7 +580,7 @@ static int cardos_format() return 1; } - if (apdu.resp[3] =! 0xff) { + if (apdu.resp[3] != 0xff) { printf("startkey version is 0x%02x, currently we support only 0xff\n", (int) apdu.resp[3]); printf("aborting\n"); return 1; From e95b0662f6549644f87f54a65d842c6114ddd85c Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:21:39 +0000 Subject: [PATCH 50/57] Fix compiler warning git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3836 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/tools/eidenv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/tools/eidenv.c b/src/tools/eidenv.c index e718a09b..21235e79 100644 --- a/src/tools/eidenv.c +++ b/src/tools/eidenv.c @@ -422,12 +422,10 @@ int main(int argc, char **argv) } if (exec_program) { - const char *largv[2]; + char *const largv[] = {exec_program, NULL}; sc_unlock(card); sc_disconnect_card(card, 0); sc_release_context(ctx); - largv[0] = exec_program; - largv[1] = NULL; execv(exec_program, largv); /* we should not get here */ perror("execv()"); From 2dfbf4f934c9be535ca891e059dd2e54664930c4 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:21:58 +0000 Subject: [PATCH 51/57] Fix compiler warnings git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3837 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/tools/westcos-tool.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tools/westcos-tool.c b/src/tools/westcos-tool.c index 8e953735..9b801453 100644 --- a/src/tools/westcos-tool.c +++ b/src/tools/westcos-tool.c @@ -270,7 +270,6 @@ static int creation_fichier_cert(sc_card_t *card) int size; sc_path_t path; sc_file_t *file = NULL; - sc_context_t *ctx = card->ctx; sc_format_path("3F00", &path); r = sc_select_file(card, &path, &file); @@ -729,7 +728,7 @@ int main(int argc, char *argv[]) file->path = path; - printf("File key creation %s, size %d.\n", file->path.value, + printf("File key creation %s, size %zd.\n", file->path.value, file->size); r = sc_create_file(card, file); @@ -746,7 +745,7 @@ int main(int argc, char *argv[]) } } - printf("Private key length is %d\n", lg); + printf("Private key length is %zd\n", lg); printf("Write private key.\n"); r = sc_update_binary(card,0,pdata,lg,0); @@ -763,7 +762,7 @@ int main(int argc, char *argv[]) r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg); if(r) goto out; - printf("Public key length %d\n", lg); + printf("Public key length %zd\n", lg); sc_format_path("3F000002", &path); r = sc_select_file(card, &path, NULL); From 84de38855fc242204518aa06f596da4aba687474 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:23:16 +0000 Subject: [PATCH 52/57] Fix a compiler warning git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3838 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/pkcs11/sc-pkcs11.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkcs11/sc-pkcs11.h b/src/pkcs11/sc-pkcs11.h index 2b85bec6..49ff9d1c 100644 --- a/src/pkcs11/sc-pkcs11.h +++ b/src/pkcs11/sc-pkcs11.h @@ -67,7 +67,7 @@ struct sc_pkcs11_card; /* Object Pool */ struct sc_pkcs11_pool_item { - int handle; + unsigned long int handle; void *item; struct sc_pkcs11_pool_item *next; struct sc_pkcs11_pool_item *prev; From 38ba3ad18d0b6dbe33c7e98bbefcdb2eb3c6bb7f Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:32:12 +0000 Subject: [PATCH 53/57] Remove card->finish() functions that do nothing git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3839 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-acos5.c | 6 ------ src/libopensc/card-asepcos.c | 6 ------ src/libopensc/card-cardos.c | 6 ------ src/libopensc/card-default.c | 6 ------ src/libopensc/card-ias.c | 6 ------ src/libopensc/card-incrypto34.c | 6 ------ src/libopensc/card-miocos.c | 6 ------ src/libopensc/card-myeid.c | 7 ------- src/libopensc/card-rtecp.c | 1 - src/libopensc/card-setcos.c | 6 ------ 10 files changed, 56 deletions(-) diff --git a/src/libopensc/card-acos5.c b/src/libopensc/card-acos5.c index 8e239187..ccea424e 100644 --- a/src/libopensc/card-acos5.c +++ b/src/libopensc/card-acos5.c @@ -54,11 +54,6 @@ static int acos5_init(sc_card_t * card) return SC_SUCCESS; } -static int acos5_finish(sc_card_t * card) -{ - return SC_SUCCESS; -} - static int acos5_select_file_by_path(sc_card_t * card, const sc_path_t * in_path, sc_file_t ** file_out) @@ -225,7 +220,6 @@ static struct sc_card_driver *sc_get_driver(void) acos5_ops.match_card = acos5_match_card; acos5_ops.init = acos5_init; - acos5_ops.finish = acos5_finish; acos5_ops.select_file = acos5_select_file; acos5_ops.card_ctl = acos5_card_ctl; acos5_ops.list_files = acos5_list_files; diff --git a/src/libopensc/card-asepcos.c b/src/libopensc/card-asepcos.c index 317639f1..4cfe4b3a 100644 --- a/src/libopensc/card-asepcos.c +++ b/src/libopensc/card-asepcos.c @@ -39,11 +39,6 @@ static struct sc_atr_table asepcos_atrs[] = { { NULL, NULL, NULL, 0, 0, NULL } }; -static int asepcos_finish(sc_card_t *card) -{ - return SC_SUCCESS; -} - static int asepcos_match_card(sc_card_t *card) { int i = _sc_match_atr(card, asepcos_atrs, &card->type); @@ -1098,7 +1093,6 @@ static struct sc_card_driver * sc_get_driver(void) asepcos_ops = *iso_ops; asepcos_ops.match_card = asepcos_match_card; asepcos_ops.init = asepcos_init; - asepcos_ops.finish = asepcos_finish; asepcos_ops.select_file = asepcos_select_file; asepcos_ops.set_security_env = asepcos_set_security_env; asepcos_ops.decipher = asepcos_decipher; diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c index 1ca70753..506a66ed 100644 --- a/src/libopensc/card-cardos.c +++ b/src/libopensc/card-cardos.c @@ -53,11 +53,6 @@ static struct sc_atr_table cardos_atrs[] = { { NULL, NULL, NULL, 0, 0, NULL } }; -static int cardos_finish(sc_card_t *card) -{ - return 0; -} - static int cardos_match_card(sc_card_t *card) { int i; @@ -1178,7 +1173,6 @@ static struct sc_card_driver * sc_get_driver(void) cardos_ops = *iso_ops; cardos_ops.match_card = cardos_match_card; cardos_ops.init = cardos_init; - cardos_ops.finish = cardos_finish; cardos_ops.select_file = cardos_select_file; cardos_ops.create_file = cardos_create_file; cardos_ops.set_security_env = cardos_set_security_env; diff --git a/src/libopensc/card-default.c b/src/libopensc/card-default.c index 70e5c26c..2408b0ef 100644 --- a/src/libopensc/card-default.c +++ b/src/libopensc/card-default.c @@ -29,11 +29,6 @@ static struct sc_card_driver default_drv = { NULL, 0, NULL }; -static int default_finish(sc_card_t *card) -{ - return SC_SUCCESS; -} - static int default_match_card(sc_card_t *card) { return 1; /* always match */ @@ -124,7 +119,6 @@ static struct sc_card_driver * sc_get_driver(void) default_ops = *iso_drv->ops; default_ops.match_card = default_match_card; default_ops.init = default_init; - default_ops.finish = default_finish; return &default_drv; } diff --git a/src/libopensc/card-ias.c b/src/libopensc/card-ias.c index 2fadbe57..476ceaf3 100644 --- a/src/libopensc/card-ias.c +++ b/src/libopensc/card-ias.c @@ -106,11 +106,6 @@ static int ias_init(sc_card_t *card) return SC_SUCCESS; } -static int ias_finish(sc_card_t *card) -{ - return SC_SUCCESS; -} - static int ias_match_card(sc_card_t *card) { int i; @@ -535,7 +530,6 @@ static struct sc_card_driver *sc_get_driver(void) ias_ops.select_file = ias_select_file; ias_ops.match_card = ias_match_card; ias_ops.init = ias_init; - ias_ops.finish = ias_finish; ias_ops.set_security_env = ias_set_security_env; ias_ops.compute_signature = ias_compute_signature; ias_ops.pin_cmd = ias_pin_cmd; diff --git a/src/libopensc/card-incrypto34.c b/src/libopensc/card-incrypto34.c index 15685d03..c8c8a65e 100644 --- a/src/libopensc/card-incrypto34.c +++ b/src/libopensc/card-incrypto34.c @@ -49,11 +49,6 @@ static struct sc_atr_table incrypto34_atrs[] = { { NULL, NULL, NULL, 0, 0, NULL } }; -static int incrypto34_finish(struct sc_card *card) -{ - return 0; -} - static int incrypto34_match_card(struct sc_card *card) { int i; @@ -909,7 +904,6 @@ static struct sc_card_driver * sc_get_driver(void) incrypto34_ops = *iso_ops; incrypto34_ops.match_card = incrypto34_match_card; incrypto34_ops.init = incrypto34_init; - incrypto34_ops.finish = incrypto34_finish; incrypto34_ops.select_file = incrypto34_select_file; incrypto34_ops.create_file = incrypto34_create_file; incrypto34_ops.set_security_env = incrypto34_set_security_env; diff --git a/src/libopensc/card-miocos.c b/src/libopensc/card-miocos.c index cb4050be..351308ff 100644 --- a/src/libopensc/card-miocos.c +++ b/src/libopensc/card-miocos.c @@ -40,11 +40,6 @@ static struct sc_card_driver miocos_drv = { NULL, 0, NULL }; -static int miocos_finish(sc_card_t *card) -{ - return 0; -} - static int miocos_match_card(sc_card_t *card) { int i; @@ -488,7 +483,6 @@ static struct sc_card_driver * sc_get_driver(void) miocos_ops = *iso_drv->ops; miocos_ops.match_card = miocos_match_card; miocos_ops.init = miocos_init; - miocos_ops.finish = miocos_finish; if (iso_ops == NULL) iso_ops = iso_drv->ops; miocos_ops.create_file = miocos_create_file; diff --git a/src/libopensc/card-myeid.c b/src/libopensc/card-myeid.c index 26459a42..0799efb3 100644 --- a/src/libopensc/card-myeid.c +++ b/src/libopensc/card-myeid.c @@ -46,12 +46,6 @@ static const char *myeid_atrs[] = { NULL }; - -static int myeid_finish(struct sc_card *card) -{ - return 0; -} - static int myeid_match_card(struct sc_card *card) { int i, match = -1; @@ -1037,7 +1031,6 @@ static struct sc_card_driver * sc_get_driver(void) myeid_ops = *iso_drv->ops; myeid_ops.match_card = myeid_match_card; myeid_ops.init = myeid_init; - myeid_ops.finish = myeid_finish; if (iso_ops == NULL) iso_ops = iso_drv->ops; myeid_ops.read_binary = myeid_read_binary; diff --git a/src/libopensc/card-rtecp.c b/src/libopensc/card-rtecp.c index 402c7a82..877bc2bd 100644 --- a/src/libopensc/card-rtecp.c +++ b/src/libopensc/card-rtecp.c @@ -785,7 +785,6 @@ struct sc_card_driver * sc_get_rtecp_driver(void) rtecp_ops.match_card = rtecp_match_card; rtecp_ops.init = rtecp_init; - rtecp_ops.finish = NULL; /* read_binary */ rtecp_ops.write_binary = NULL; /* update_binary */ diff --git a/src/libopensc/card-setcos.c b/src/libopensc/card-setcos.c index b0ad094e..a17ea5ec 100644 --- a/src/libopensc/card-setcos.c +++ b/src/libopensc/card-setcos.c @@ -70,11 +70,6 @@ static struct sc_card_driver setcos_drv = { NULL, 0, NULL }; -static int setcos_finish(sc_card_t *card) -{ - return 0; -} - static int match_hist_bytes(sc_card_t *card, const char *str, size_t len) { const char *src = (const char *) card->slot->atr_info.hist_bytes; @@ -1120,7 +1115,6 @@ static struct sc_card_driver *sc_get_driver(void) setcos_ops = *iso_drv->ops; setcos_ops.match_card = setcos_match_card; setcos_ops.init = setcos_init; - setcos_ops.finish = setcos_finish; if (iso_ops == NULL) iso_ops = iso_drv->ops; setcos_ops.create_file = setcos_create_file; From ca0976ba6f7860cc82a1e3d308bf427437262719 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 11:48:17 +0000 Subject: [PATCH 54/57] Remove signer and related configure elements git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3840 c6295689-39f2-0310-b995-f0e70906c6a9 --- configure.ac | 38 -- src/Makefile.am | 2 +- src/signer/Makefile.am | 27 - src/signer/dialog.c | 112 ---- src/signer/npinclude/Makefile.am | 3 - src/signer/npinclude/jri.h | 638 -------------------- src/signer/npinclude/jri_md.h | 500 ---------------- src/signer/npinclude/jritypes.h | 180 ------ src/signer/npinclude/npapi.h | 396 ------------ src/signer/npinclude/npunix.c | 406 ------------- src/signer/npinclude/npupp.h | 995 ------------------------------- src/signer/opensc-crypto.c | 228 ------- src/signer/opensc-crypto.h | 18 - src/signer/opensc-support.c | 242 -------- src/signer/opensc-support.h | 8 - src/signer/signer.c | 374 ------------ src/signer/signer.exports | 34 -- src/signer/signer.h | 35 -- src/signer/stubs.c | 14 - src/signer/testprog.c | 48 -- 20 files changed, 1 insertion(+), 4297 deletions(-) delete mode 100644 src/signer/Makefile.am delete mode 100644 src/signer/dialog.c delete mode 100644 src/signer/npinclude/Makefile.am delete mode 100644 src/signer/npinclude/jri.h delete mode 100644 src/signer/npinclude/jri_md.h delete mode 100644 src/signer/npinclude/jritypes.h delete mode 100644 src/signer/npinclude/npapi.h delete mode 100644 src/signer/npinclude/npunix.c delete mode 100644 src/signer/npinclude/npupp.h delete mode 100644 src/signer/opensc-crypto.c delete mode 100644 src/signer/opensc-crypto.h delete mode 100644 src/signer/opensc-support.c delete mode 100644 src/signer/opensc-support.h delete mode 100644 src/signer/signer.c delete mode 100644 src/signer/signer.exports delete mode 100644 src/signer/signer.h delete mode 100644 src/signer/stubs.c delete mode 100644 src/signer/testprog.c diff --git a/configure.ac b/configure.ac index 72a4d34e..a55f38fd 100644 --- a/configure.ac +++ b/configure.ac @@ -158,13 +158,6 @@ AC_ARG_ENABLE( [enable_pcsc="yes"] ) -AC_ARG_ENABLE( - [nsplugin], - [AS_HELP_STRING([--enable-nsplugin],[enable nsplugin (signer) @<:@disabled@:>@])], - , - [enable_nsplugin="no"] -) - AC_ARG_ENABLE( [man], [AS_HELP_STRING([--disable-man],[disable installation of manuals @<:@enabled for none Windows@:>@])], @@ -206,13 +199,6 @@ AC_ARG_WITH( [with_pcsc_provider="detect"] ) -AC_ARG_WITH( - [pinentry], - [AS_HELP_STRING([--with-pinentry=PROG],[run PROG as PIN-entry for OpenSC Signer @<:/usr/bin/gpinentry:>@])], - , - [with_pinentry="/usr/bin/gpinentry"] -) - dnl Checks for programs. AC_PROG_CPP AC_PROG_INSTALL @@ -597,21 +583,6 @@ if test "${enable_pcsc}" = "yes"; then AC_DEFINE([ENABLE_PCSC], [1], [Define if PC/SC is to be enabled]) fi -dnl AM_PATH_LIBASSUAN([MINIMUM-VERSION, -dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) -dnl Test for libassuan and define LIBASSUAN_CFLAGS and LIBASSUAN_LIBS -AM_PATH_LIBASSUAN( - , - [have_assuan="yes"], - [have_assuan="no"] -) - -if test "${enable_nsplugin}" = "yes"; then - if test "x${have_assuan}" != "xyes" -o "x${have_openssl}" != "xyes"; then - AC_MSG_ERROR([nsplugin requires assuan and openssl]) - fi -fi - OPENSC_FEATURES="" if test "${enable_zlib}" = "yes"; then OPENSC_FEATURES="${OPENSC_FEATURES} zlib" @@ -642,12 +613,10 @@ if test "${enable_pcsc}" = "yes"; then OPENSC_FEATURES="${OPENSC_FEATURES} pcsc(${DEFAULT_PCSC_PROVIDER})" OPTIONAL_PCSC_CFLAGS="${PCSC_CFLAGS}" fi -test "${enable_nsplugin}" = "yes" && OPENSC_FEATURES="${OPENSC_FEATURES} nsplugin" AC_DEFINE_UNQUOTED([OPENSC_VERSION_MAJOR], [${OPENSC_VERSION_MAJOR}], [OpenSC version major component]) AC_DEFINE_UNQUOTED([OPENSC_VERSION_MINOR], [${OPENSC_VERSION_MINOR}], [OpenSC version minor component]) AC_DEFINE_UNQUOTED([OPENSC_VERSION_FIX], [${OPENSC_VERSION_FIX}], [OpenSC version fix component]) -test "${with_pinentry}" != "no" && AC_DEFINE_UNQUOTED([PIN_ENTRY], ["${with_pinentry}"], [PIN-entry program for OpenSC Signer]) AC_DEFINE_UNQUOTED([OPENSC_FEATURES], ["${OPENSC_FEATURES}"], [Enabled OpenSC features]) openscincludedir="\$(includedir)/opensc" @@ -687,7 +656,6 @@ AM_CONDITIONAL([ENABLE_READLINE], [test "${enable_readline}" = "yes"]) AM_CONDITIONAL([ENABLE_ICONV], [test "${enable_iconv}" = "yes"]) AM_CONDITIONAL([ENABLE_OPENSSL], [test "${enable_openssl}" = "yes"]) AM_CONDITIONAL([ENABLE_OPENCT], [test "${enable_openct}" = "yes"]) -AM_CONDITIONAL([ENABLE_NSPLUGIN], [test "${enable_nsplugin}" = "yes"]) AM_CONDITIONAL([ENABLE_DOC], [test "${enable_doc}" = "yes"]) AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) AM_CONDITIONAL([CYGWIN], [test "${CYGWIN}" = "yes"]) @@ -723,8 +691,6 @@ AC_CONFIG_FILES([ src/pkcs11/Makefile src/pkcs15init/Makefile src/scconf/Makefile - src/signer/Makefile - src/signer/npinclude/Makefile src/tests/Makefile src/tests/regression/Makefile src/tools/Makefile @@ -751,10 +717,8 @@ iconv support: ${enable_iconv} OpenSSL support: ${enable_openssl} PC/SC support: ${enable_pcsc} OpenCT support: ${enable_openct} -NSPlugin support: ${enable_nsplugin} PC/SC default provider: ${DEFAULT_PCSC_PROVIDER} -pinentry: ${with_pinentry} Host: ${host} Compiler: ${CC} @@ -776,8 +740,6 @@ OPENSSL_LIBS: ${OPENSSL_LIBS} OPENCT_CFLAGS: ${OPENCT_CFLAGS} OPENCT_LIBS: ${OPENCT_LIBS} PCSC_CFLAGS: ${PCSC_CFLAGS} -LIBASSUAN_CFLAGS: ${LIBASSUAN_CFLAGS} -LIBASSUAN_LIBS: ${LIBASSUAN_LIBS} EOF diff --git a/src/Makefile.am b/src/Makefile.am index b6407606..af49e855 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,4 +3,4 @@ EXTRA_DIST = Makefile.mak # Order IS important SUBDIRS = common include scconf libopensc pkcs15init pkcs11 \ - tests tools openssh signer + tests tools openssh diff --git a/src/signer/Makefile.am b/src/signer/Makefile.am deleted file mode 100644 index de61c6bd..00000000 --- a/src/signer/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -SUBDIRS = npinclude -if ENABLE_NSPLUGIN -noinst_HEADERS = opensc-crypto.h opensc-support.h signer.h -lib_LTLIBRARIES = opensc-signer.la -dist_noinst_DATA = testprog.c -endif - -AM_CFLAGS = $(OPENSSL_CFLAGS) $(LIBASSUAN_CFLAGS) -INCLUDES = -I$(srcdir)/npinclude -I$(top_builddir)/src/include - -opensc_signer_la_CFLAGS = $(AM_CFLAGS) -DXP_UNIX -opensc_signer_la_SOURCES = opensc-crypto.c opensc-support.c signer.c stubs.c dialog.c \ - signer.exports -opensc_signer_la_LIBADD = $(OPENSSL_LIBS) $(LIBASSUAN_LIBS) \ - $(top_builddir)/src/libopensc/libopensc.la -opensc_signer_la_LDFLAGS = $(AM_LDFLAGS) \ - -export-symbols "$(srcdir)/signer.exports" \ - -module -avoid-version -no-undefined - -if ENABLE_NSPLUGIN -plugin_DATA=#Create directory -install-exec-hook: install-pluginDATA - -rm -f "$(DESTDIR)$(plugindir)/opensc-signer.so" - $(LN_S) "$(libdir)/opensc-signer.so" "$(DESTDIR)$(plugindir)" -endif diff --git a/src/signer/dialog.c b/src/signer/dialog.c deleted file mode 100644 index c66f4346..00000000 --- a/src/signer/dialog.c +++ /dev/null @@ -1,112 +0,0 @@ -#include "signer.h" -#include -#include - -#ifndef PIN_ENTRY -#define PIN_ENTRY "/usr/local/bin/gpinentry" -#endif - -extern int ask_and_verify_pin_code(struct sc_pkcs15_card *p15card, - struct sc_pkcs15_object *pin); - -struct entry_parm_s { - int lines; - size_t size; - char *buffer; -}; - -static AssuanError -getpin_cb (void *opaque, const void *buffer, size_t length) -{ - struct entry_parm_s *parm = (struct entry_parm_s *) opaque; - - /* we expect the pin to fit on one line */ - if (parm->lines || length >= parm->size) - return ASSUAN_Too_Much_Data; - - /* fixme: we should make sure that the assuan buffer is allocated in - secure memory or read the response byte by byte */ - memcpy(parm->buffer, buffer, length); - parm->buffer[length] = 0; - parm->lines++; - return (AssuanError) 0; -} - -int ask_and_verify_pin_code(struct sc_pkcs15_card *p15card, - struct sc_pkcs15_object *pin) -{ - int r; - size_t len; - const char *argv[3]; - const char *pgmname = PIN_ENTRY; - ASSUAN_CONTEXT ctx; - char buf[500]; - char errtext[100]; - struct entry_parm_s parm; - struct sc_pkcs15_pin_info *pinfo = (struct sc_pkcs15_pin_info *) pin->data; - - argv[0] = pgmname; - argv[1] = NULL; - - r = assuan_pipe_connect(&ctx, pgmname, (char **) argv, NULL); - if (r) { - printf("Can't connect to the PIN entry module: %s\n", - assuan_strerror((AssuanError) r)); - goto err; - } - sprintf(buf, "SETDESC Enter PIN [%s] for digital signing ", pin->label); - r = assuan_transact(ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL); - if (r) { - printf("SETDESC: %s\n", assuan_strerror((AssuanError) r)); - goto err; - } - errtext[0] = 0; - while (1) { - if (errtext[0]) { - sprintf(buf, "SETERROR %s", errtext); - r = assuan_transact(ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL); - errtext[0] = 0; - } - parm.lines = 0; - parm.size = sizeof(buf); - parm.buffer = buf; - r = assuan_transact(ctx, "GETPIN", getpin_cb, &parm, NULL, NULL, NULL, NULL); - if (r == ASSUAN_Canceled) { - assuan_disconnect(ctx); - return -2; - } - if (r) { - printf("GETPIN: %s\n", assuan_strerror((AssuanError) r)); - goto err; - } - len = strlen(buf); - if (len < pinfo->min_length) { - sprintf(errtext, "PIN code too short, min. %lu digits", (unsigned long) pinfo->min_length); - continue; - } - if (len > pinfo->max_length) { - sprintf(errtext, "PIN code too long, max. %lu digits", (unsigned long) pinfo->max_length); - continue; - } - r = sc_pkcs15_verify_pin(p15card, pinfo, (const u8 *) buf, strlen(buf)); - switch (r) { - case SC_ERROR_PIN_CODE_INCORRECT: - sprintf(errtext, "PIN code incorrect (%d %s left)", - pinfo->tries_left, pinfo->tries_left == 1 ? - "try" : "tries"); - break; - case 0: - break; - default: - goto err; - } - if (r == 0) - break; - } - - assuan_disconnect(ctx); - return 0; -err: - assuan_disconnect(ctx); - return -1; -} diff --git a/src/signer/npinclude/Makefile.am b/src/signer/npinclude/Makefile.am deleted file mode 100644 index 5e8fcf7e..00000000 --- a/src/signer/npinclude/Makefile.am +++ /dev/null @@ -1,3 +0,0 @@ -MAINTAINERCLEANFILES = $(srcdir)/Makefile.in - -noinst_HEADERS = jri.h jri_md.h jritypes.h npapi.h npunix.c npupp.h diff --git a/src/signer/npinclude/jri.h b/src/signer/npinclude/jri.h deleted file mode 100644 index d2bf291a..00000000 --- a/src/signer/npinclude/jri.h +++ /dev/null @@ -1,638 +0,0 @@ -/* -*- Mode: C; tab-width: 4; -*- */ -/******************************************************************************* - * Java Runtime Interface - * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. - ******************************************************************************/ - -#ifndef JRI_H -#define JRI_H - -#include "jritypes.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/******************************************************************************* - * JRIEnv - ******************************************************************************/ - -/* The type of the JRIEnv interface. */ -typedef struct JRIEnvInterface JRIEnvInterface; - -/* The type of a JRIEnv instance. */ -typedef const JRIEnvInterface* JRIEnv; - -/******************************************************************************* - * JRIEnv Operations - ******************************************************************************/ - -#define JRI_LoadClass(env, buf, bufLen) \ - (((*(env))->LoadClass)(env, JRI_LoadClass_op, buf, bufLen)) - -#define JRI_FindClass(env, name) \ - (((*(env))->FindClass)(env, JRI_FindClass_op, name)) - -#define JRI_Throw(env, obj) \ - (((*(env))->Throw)(env, JRI_Throw_op, obj)) - -#define JRI_ThrowNew(env, clazz, message) \ - (((*(env))->ThrowNew)(env, JRI_ThrowNew_op, clazz, message)) - -#define JRI_ExceptionOccurred(env) \ - (((*(env))->ExceptionOccurred)(env, JRI_ExceptionOccurred_op)) - -#define JRI_ExceptionDescribe(env) \ - (((*(env))->ExceptionDescribe)(env, JRI_ExceptionDescribe_op)) - -#define JRI_ExceptionClear(env) \ - (((*(env))->ExceptionClear)(env, JRI_ExceptionClear_op)) - -#define JRI_NewGlobalRef(env, ref) \ - (((*(env))->NewGlobalRef)(env, JRI_NewGlobalRef_op, ref)) - -#define JRI_DisposeGlobalRef(env, gref) \ - (((*(env))->DisposeGlobalRef)(env, JRI_DisposeGlobalRef_op, gref)) - -#define JRI_GetGlobalRef(env, gref) \ - (((*(env))->GetGlobalRef)(env, JRI_GetGlobalRef_op, gref)) - -#define JRI_SetGlobalRef(env, gref, ref) \ - (((*(env))->SetGlobalRef)(env, JRI_SetGlobalRef_op, gref, ref)) - -#define JRI_IsSameObject(env, a, b) \ - (((*(env))->IsSameObject)(env, JRI_IsSameObject_op, a, b)) - -#define JRI_NewObject(env) ((*(env))->NewObject) -#define JRI_NewObjectV(env, clazz, methodID, args) \ - (((*(env))->NewObjectV)(env, JRI_NewObject_op_va_list, clazz, methodID, args)) -#define JRI_NewObjectA(env, clazz, method, args) \ - (((*(env))->NewObjectA)(env, JRI_NewObject_op_array, clazz, methodID, args)) - -#define JRI_GetObjectClass(env, obj) \ - (((*(env))->GetObjectClass)(env, JRI_GetObjectClass_op, obj)) - -#define JRI_IsInstanceOf(env, obj, clazz) \ - (((*(env))->IsInstanceOf)(env, JRI_IsInstanceOf_op, obj, clazz)) - -#define JRI_GetMethodID(env, clazz, name, sig) \ - (((*(env))->GetMethodID)(env, JRI_GetMethodID_op, clazz, name, sig)) - -#define JRI_CallMethod(env) ((*(env))->CallMethod) -#define JRI_CallMethodV(env, obj, methodID, args) \ - (((*(env))->CallMethodV)(env, JRI_CallMethod_op_va_list, obj, methodID, args)) -#define JRI_CallMethodA(env, obj, methodID, args) \ - (((*(env))->CallMethodA)(env, JRI_CallMethod_op_array, obj, methodID, args)) - -#define JRI_CallMethodBoolean(env) ((*(env))->CallMethodBoolean) -#define JRI_CallMethodBooleanV(env, obj, methodID, args) \ - (((*(env))->CallMethodBooleanV)(env, JRI_CallMethodBoolean_op_va_list, obj, methodID, args)) -#define JRI_CallMethodBooleanA(env, obj, methodID, args) \ - (((*(env))->CallMethodBooleanA)(env, JRI_CallMethodBoolean_op_array, obj, methodID, args)) - -#define JRI_CallMethodByte(env) ((*(env))->CallMethodByte) -#define JRI_CallMethodByteV(env, obj, methodID, args) \ - (((*(env))->CallMethodByteV)(env, JRI_CallMethodByte_op_va_list, obj, methodID, args)) -#define JRI_CallMethodByteA(env, obj, methodID, args) \ - (((*(env))->CallMethodByteA)(env, JRI_CallMethodByte_op_array, obj, methodID, args)) - -#define JRI_CallMethodChar(env) ((*(env))->CallMethodChar) -#define JRI_CallMethodCharV(env, obj, methodID, args) \ - (((*(env))->CallMethodCharV)(env, JRI_CallMethodChar_op_va_list, obj, methodID, args)) -#define JRI_CallMethodCharA(env, obj, methodID, args) \ - (((*(env))->CallMethodCharA)(env, JRI_CallMethodChar_op_array, obj, methodID, args)) - -#define JRI_CallMethodShort(env) ((*(env))->CallMethodShort) -#define JRI_CallMethodShortV(env, obj, methodID, args) \ - (((*(env))->CallMethodShortV)(env, JRI_CallMethodShort_op_va_list, obj, methodID, args)) -#define JRI_CallMethodShortA(env, obj, methodID, args) \ - (((*(env))->CallMethodShortA)(env, JRI_CallMethodShort_op_array, obj, methodID, args)) - -#define JRI_CallMethodInt(env) ((*(env))->CallMethodInt) -#define JRI_CallMethodIntV(env, obj, methodID, args) \ - (((*(env))->CallMethodIntV)(env, JRI_CallMethodInt_op_va_list, obj, methodID, args)) -#define JRI_CallMethodIntA(env, obj, methodID, args) \ - (((*(env))->CallMethodIntA)(env, JRI_CallMethodInt_op_array, obj, methodID, args)) - -#define JRI_CallMethodLong(env) ((*(env))->CallMethodLong) -#define JRI_CallMethodLongV(env, obj, methodID, args) \ - (((*(env))->CallMethodLongV)(env, JRI_CallMethodLong_op_va_list, obj, methodID, args)) -#define JRI_CallMethodLongA(env, obj, methodID, args) \ - (((*(env))->CallMethodLongA)(env, JRI_CallMethodLong_op_array, obj, methodID, args)) - -#define JRI_CallMethodFloat(env) ((*(env))->CallMethodFloat) -#define JRI_CallMethodFloatV(env, obj, methodID, args) \ - (((*(env))->CallMethodFloatV)(env, JRI_CallMethodFloat_op_va_list, obj, methodID, args)) -#define JRI_CallMethodFloatA(env, obj, methodID, args) \ - (((*(env))->CallMethodFloatA)(env, JRI_CallMethodFloat_op_array, obj, methodID, args)) - -#define JRI_CallMethodDouble(env) ((*(env))->CallMethodDouble) -#define JRI_CallMethodDoubleV(env, obj, methodID, args) \ - (((*(env))->CallMethodDoubleV)(env, JRI_CallMethodDouble_op_va_list, obj, methodID, args)) -#define JRI_CallMethodDoubleA(env, obj, methodID, args) \ - (((*(env))->CallMethodDoubleA)(env, JRI_CallMethodDouble_op_array, obj, methodID, args)) - -#define JRI_GetFieldID(env, clazz, name, sig) \ - (((*(env))->GetFieldID)(env, JRI_GetFieldID_op, clazz, name, sig)) - -#define JRI_GetField(env, obj, fieldID) \ - (((*(env))->GetField)(env, JRI_GetField_op, obj, fieldID)) - -#define JRI_GetFieldBoolean(env, obj, fieldID) \ - (((*(env))->GetFieldBoolean)(env, JRI_GetFieldBoolean_op, obj, fieldID)) - -#define JRI_GetFieldByte(env, obj, fieldID) \ - (((*(env))->GetFieldByte)(env, JRI_GetFieldByte_op, obj, fieldID)) - -#define JRI_GetFieldChar(env, obj, fieldID) \ - (((*(env))->GetFieldChar)(env, JRI_GetFieldChar_op, obj, fieldID)) - -#define JRI_GetFieldShort(env, obj, fieldID) \ - (((*(env))->GetFieldShort)(env, JRI_GetFieldShort_op, obj, fieldID)) - -#define JRI_GetFieldInt(env, obj, fieldID) \ - (((*(env))->GetFieldInt)(env, JRI_GetFieldInt_op, obj, fieldID)) - -#define JRI_GetFieldLong(env, obj, fieldID) \ - (((*(env))->GetFieldLong)(env, JRI_GetFieldLong_op, obj, fieldID)) - -#define JRI_GetFieldFloat(env, obj, fieldID) \ - (((*(env))->GetFieldFloat)(env, JRI_GetFieldFloat_op, obj, fieldID)) - -#define JRI_GetFieldDouble(env, obj, fieldID) \ - (((*(env))->GetFieldDouble)(env, JRI_GetFieldDouble_op, obj, fieldID)) - -#define JRI_SetField(env, obj, fieldID, value) \ - (((*(env))->SetField)(env, JRI_SetField_op, obj, fieldID, value)) - -#define JRI_SetFieldBoolean(env, obj, fieldID, value) \ - (((*(env))->SetFieldBoolean)(env, JRI_SetFieldBoolean_op, obj, fieldID, value)) - -#define JRI_SetFieldByte(env, obj, fieldID, value) \ - (((*(env))->SetFieldByte)(env, JRI_SetFieldByte_op, obj, fieldID, value)) - -#define JRI_SetFieldChar(env, obj, fieldID, value) \ - (((*(env))->SetFieldChar)(env, JRI_SetFieldChar_op, obj, fieldID, value)) - -#define JRI_SetFieldShort(env, obj, fieldID, value) \ - (((*(env))->SetFieldShort)(env, JRI_SetFieldShort_op, obj, fieldID, value)) - -#define JRI_SetFieldInt(env, obj, fieldID, value) \ - (((*(env))->SetFieldInt)(env, JRI_SetFieldInt_op, obj, fieldID, value)) - -#define JRI_SetFieldLong(env, obj, fieldID, value) \ - (((*(env))->SetFieldLong)(env, JRI_SetFieldLong_op, obj, fieldID, value)) - -#define JRI_SetFieldFloat(env, obj, fieldID, value) \ - (((*(env))->SetFieldFloat)(env, JRI_SetFieldFloat_op, obj, fieldID, value)) - -#define JRI_SetFieldDouble(env, obj, fieldID, value) \ - (((*(env))->SetFieldDouble)(env, JRI_SetFieldDouble_op, obj, fieldID, value)) - -#define JRI_IsSubclassOf(env, a, b) \ - (((*(env))->IsSubclassOf)(env, JRI_IsSubclassOf_op, a, b)) - -#define JRI_GetStaticMethodID(env, clazz, name, sig) \ - (((*(env))->GetStaticMethodID)(env, JRI_GetStaticMethodID_op, clazz, name, sig)) - -#define JRI_CallStaticMethod(env) ((*(env))->CallStaticMethod) -#define JRI_CallStaticMethodV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodV)(env, JRI_CallStaticMethod_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodA)(env, JRI_CallStaticMethod_op_array, clazz, methodID, args)) - -#define JRI_CallStaticMethodBoolean(env) ((*(env))->CallStaticMethodBoolean) -#define JRI_CallStaticMethodBooleanV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodBooleanV)(env, JRI_CallStaticMethodBoolean_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodBooleanA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodBooleanA)(env, JRI_CallStaticMethodBoolean_op_array, clazz, methodID, args)) - -#define JRI_CallStaticMethodByte(env) ((*(env))->CallStaticMethodByte) -#define JRI_CallStaticMethodByteV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodByteV)(env, JRI_CallStaticMethodByte_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodByteA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodByteA)(env, JRI_CallStaticMethodByte_op_array, clazz, methodID, args)) - -#define JRI_CallStaticMethodChar(env) ((*(env))->CallStaticMethodChar) -#define JRI_CallStaticMethodCharV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodCharV)(env, JRI_CallStaticMethodChar_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodCharA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodCharA)(env, JRI_CallStaticMethodChar_op_array, clazz, methodID, args)) - -#define JRI_CallStaticMethodShort(env) ((*(env))->CallStaticMethodShort) -#define JRI_CallStaticMethodShortV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodShortV)(env, JRI_CallStaticMethodShort_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodShortA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodShortA)(env, JRI_CallStaticMethodShort_op_array, clazz, methodID, args)) - -#define JRI_CallStaticMethodInt(env) ((*(env))->CallStaticMethodInt) -#define JRI_CallStaticMethodIntV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodIntV)(env, JRI_CallStaticMethodInt_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodIntA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodIntA)(env, JRI_CallStaticMethodInt_op_array, clazz, methodID, args)) - -#define JRI_CallStaticMethodLong(env) ((*(env))->CallStaticMethodLong) -#define JRI_CallStaticMethodLongV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodLongV)(env, JRI_CallStaticMethodLong_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodLongA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodLongA)(env, JRI_CallStaticMethodLong_op_array, clazz, methodID, args)) - -#define JRI_CallStaticMethodFloat(env) ((*(env))->CallStaticMethodFloat) -#define JRI_CallStaticMethodFloatV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodFloatV)(env, JRI_CallStaticMethodFloat_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodFloatA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodFloatA)(env, JRI_CallStaticMethodFloat_op_array, clazz, methodID, args)) - -#define JRI_CallStaticMethodDouble(env) ((*(env))->CallStaticMethodDouble) -#define JRI_CallStaticMethodDoubleV(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodDoubleV)(env, JRI_CallStaticMethodDouble_op_va_list, clazz, methodID, args)) -#define JRI_CallStaticMethodDoubleA(env, clazz, methodID, args) \ - (((*(env))->CallStaticMethodDoubleA)(env, JRI_CallStaticMethodDouble_op_array, clazz, methodID, args)) - -#define JRI_GetStaticFieldID(env, clazz, name, sig) \ - (((*(env))->GetStaticFieldID)(env, JRI_GetStaticFieldID_op, clazz, name, sig)) - -#define JRI_GetStaticField(env, clazz, fieldID) \ - (((*(env))->GetStaticField)(env, JRI_GetStaticField_op, clazz, fieldID)) - -#define JRI_GetStaticFieldBoolean(env, clazz, fieldID) \ - (((*(env))->GetStaticFieldBoolean)(env, JRI_GetStaticFieldBoolean_op, clazz, fieldID)) - -#define JRI_GetStaticFieldByte(env, clazz, fieldID) \ - (((*(env))->GetStaticFieldByte)(env, JRI_GetStaticFieldByte_op, clazz, fieldID)) - -#define JRI_GetStaticFieldChar(env, clazz, fieldID) \ - (((*(env))->GetStaticFieldChar)(env, JRI_GetStaticFieldChar_op, clazz, fieldID)) - -#define JRI_GetStaticFieldShort(env, clazz, fieldID) \ - (((*(env))->GetStaticFieldShort)(env, JRI_GetStaticFieldShort_op, clazz, fieldID)) - -#define JRI_GetStaticFieldInt(env, clazz, fieldID) \ - (((*(env))->GetStaticFieldInt)(env, JRI_GetStaticFieldInt_op, clazz, fieldID)) - -#define JRI_GetStaticFieldLong(env, clazz, fieldID) \ - (((*(env))->GetStaticFieldLong)(env, JRI_GetStaticFieldLong_op, clazz, fieldID)) - -#define JRI_GetStaticFieldFloat(env, clazz, fieldID) \ - (((*(env))->GetStaticFieldFloat)(env, JRI_GetStaticFieldFloat_op, clazz, fieldID)) - -#define JRI_GetStaticFieldDouble(env, clazz, fieldID) \ - (((*(env))->GetStaticFieldDouble)(env, JRI_GetStaticFieldDouble_op, clazz, fieldID)) - -#define JRI_SetStaticField(env, clazz, fieldID, value) \ - (((*(env))->SetStaticField)(env, JRI_SetStaticField_op, clazz, fieldID, value)) - -#define JRI_SetStaticFieldBoolean(env, clazz, fieldID, value) \ - (((*(env))->SetStaticFieldBoolean)(env, JRI_SetStaticFieldBoolean_op, clazz, fieldID, value)) - -#define JRI_SetStaticFieldByte(env, clazz, fieldID, value) \ - (((*(env))->SetStaticFieldByte)(env, JRI_SetStaticFieldByte_op, clazz, fieldID, value)) - -#define JRI_SetStaticFieldChar(env, clazz, fieldID, value) \ - (((*(env))->SetStaticFieldChar)(env, JRI_SetStaticFieldChar_op, clazz, fieldID, value)) - -#define JRI_SetStaticFieldShort(env, clazz, fieldID, value) \ - (((*(env))->SetStaticFieldShort)(env, JRI_SetStaticFieldShort_op, clazz, fieldID, value)) - -#define JRI_SetStaticFieldInt(env, clazz, fieldID, value) \ - (((*(env))->SetStaticFieldInt)(env, JRI_SetStaticFieldInt_op, clazz, fieldID, value)) - -#define JRI_SetStaticFieldLong(env, clazz, fieldID, value) \ - (((*(env))->SetStaticFieldLong)(env, JRI_SetStaticFieldLong_op, clazz, fieldID, value)) - -#define JRI_SetStaticFieldFloat(env, clazz, fieldID, value) \ - (((*(env))->SetStaticFieldFloat)(env, JRI_SetStaticFieldFloat_op, clazz, fieldID, value)) - -#define JRI_SetStaticFieldDouble(env, clazz, fieldID, value) \ - (((*(env))->SetStaticFieldDouble)(env, JRI_SetStaticFieldDouble_op, clazz, fieldID, value)) - -#define JRI_NewString(env, unicode, len) \ - (((*(env))->NewString)(env, JRI_NewString_op, unicode, len)) - -#define JRI_GetStringLength(env, string) \ - (((*(env))->GetStringLength)(env, JRI_GetStringLength_op, string)) - -#define JRI_GetStringChars(env, string) \ - (((*(env))->GetStringChars)(env, JRI_GetStringChars_op, string)) - -#define JRI_NewStringUTF(env, utf, len) \ - (((*(env))->NewStringUTF)(env, JRI_NewStringUTF_op, utf, len)) - -#define JRI_GetStringUTFLength(env, string) \ - (((*(env))->GetStringUTFLength)(env, JRI_GetStringUTFLength_op, string)) - -#define JRI_GetStringUTFChars(env, string) \ - (((*(env))->GetStringUTFChars)(env, JRI_GetStringUTFChars_op, string)) - -#define JRI_NewScalarArray(env, length, elementSig, initialElements) \ - (((*(env))->NewScalarArray)(env, JRI_NewScalarArray_op, length, elementSig, initialElements)) - -#define JRI_GetScalarArrayLength(env, array) \ - (((*(env))->GetScalarArrayLength)(env, JRI_GetScalarArrayLength_op, array)) - -#define JRI_GetScalarArrayElements(env, array) \ - (((*(env))->GetScalarArrayElements)(env, JRI_GetScalarArrayElements_op, array)) - -#define JRI_NewObjectArray(env, length, elementClass, initialElement) \ - (((*(env))->NewObjectArray)(env, JRI_NewObjectArray_op, length, elementClass, initialElement)) - -#define JRI_GetObjectArrayLength(env, array) \ - (((*(env))->GetObjectArrayLength)(env, JRI_GetObjectArrayLength_op, array)) - -#define JRI_GetObjectArrayElement(env, array, index) \ - (((*(env))->GetObjectArrayElement)(env, JRI_GetObjectArrayElement_op, array, index)) - -#define JRI_SetObjectArrayElement(env, array, index, value) \ - (((*(env))->SetObjectArrayElement)(env, JRI_SetObjectArrayElement_op, array, index, value)) - -#define JRI_RegisterNatives(env, clazz, nameAndSigArray, nativeProcArray) \ - (((*(env))->RegisterNatives)(env, JRI_RegisterNatives_op, clazz, nameAndSigArray, nativeProcArray)) - -#define JRI_UnregisterNatives(env, clazz) \ - (((*(env))->UnregisterNatives)(env, JRI_UnregisterNatives_op, clazz)) - -/******************************************************************************* - * JRIEnv Interface - ******************************************************************************/ - -struct java_lang_Class; -struct java_lang_Throwable; -struct java_lang_Object; -struct java_lang_String; - -struct JRIEnvInterface { - void* reserved0; - void* reserved1; - void* reserved2; - struct java_lang_Class* (*LoadClass)(JRIEnv* env, jint op, jbyte* a, jsize aLen); - struct java_lang_Class* (*FindClass)(JRIEnv* env, jint op, const char* a); - void (*Throw)(JRIEnv* env, jint op, struct java_lang_Throwable* a); - void (*ThrowNew)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b); - struct java_lang_Throwable* (*ExceptionOccurred)(JRIEnv* env, jint op); - void (*ExceptionDescribe)(JRIEnv* env, jint op); - void (*ExceptionClear)(JRIEnv* env, jint op); - jglobal (*NewGlobalRef)(JRIEnv* env, jint op, void* a); - void (*DisposeGlobalRef)(JRIEnv* env, jint op, jglobal a); - void* (*GetGlobalRef)(JRIEnv* env, jint op, jglobal a); - void (*SetGlobalRef)(JRIEnv* env, jint op, jglobal a, void* b); - jbool (*IsSameObject)(JRIEnv* env, jint op, void* a, void* b); - void* (*NewObject)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - void* (*NewObjectV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - void* (*NewObjectA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - struct java_lang_Class* (*GetObjectClass)(JRIEnv* env, jint op, void* a); - jbool (*IsInstanceOf)(JRIEnv* env, jint op, void* a, struct java_lang_Class* b); - jint (*GetMethodID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); - void* (*CallMethod)(JRIEnv* env, jint op, void* a, jint b, ...); - void* (*CallMethodV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - void* (*CallMethodA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jbool (*CallMethodBoolean)(JRIEnv* env, jint op, void* a, jint b, ...); - jbool (*CallMethodBooleanV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - jbool (*CallMethodBooleanA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jbyte (*CallMethodByte)(JRIEnv* env, jint op, void* a, jint b, ...); - jbyte (*CallMethodByteV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - jbyte (*CallMethodByteA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jchar (*CallMethodChar)(JRIEnv* env, jint op, void* a, jint b, ...); - jchar (*CallMethodCharV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - jchar (*CallMethodCharA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jshort (*CallMethodShort)(JRIEnv* env, jint op, void* a, jint b, ...); - jshort (*CallMethodShortV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - jshort (*CallMethodShortA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jint (*CallMethodInt)(JRIEnv* env, jint op, void* a, jint b, ...); - jint (*CallMethodIntV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - jint (*CallMethodIntA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jlong (*CallMethodLong)(JRIEnv* env, jint op, void* a, jint b, ...); - jlong (*CallMethodLongV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - jlong (*CallMethodLongA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jfloat (*CallMethodFloat)(JRIEnv* env, jint op, void* a, jint b, ...); - jfloat (*CallMethodFloatV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - jfloat (*CallMethodFloatA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jdouble (*CallMethodDouble)(JRIEnv* env, jint op, void* a, jint b, ...); - jdouble (*CallMethodDoubleV)(JRIEnv* env, jint op, void* a, jint b, va_list c); - jdouble (*CallMethodDoubleA)(JRIEnv* env, jint op, void* a, jint b, JRIValue* c); - jint (*GetFieldID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); - void* (*GetField)(JRIEnv* env, jint op, void* a, jint b); - jbool (*GetFieldBoolean)(JRIEnv* env, jint op, void* a, jint b); - jbyte (*GetFieldByte)(JRIEnv* env, jint op, void* a, jint b); - jchar (*GetFieldChar)(JRIEnv* env, jint op, void* a, jint b); - jshort (*GetFieldShort)(JRIEnv* env, jint op, void* a, jint b); - jint (*GetFieldInt)(JRIEnv* env, jint op, void* a, jint b); - jlong (*GetFieldLong)(JRIEnv* env, jint op, void* a, jint b); - jfloat (*GetFieldFloat)(JRIEnv* env, jint op, void* a, jint b); - jdouble (*GetFieldDouble)(JRIEnv* env, jint op, void* a, jint b); - void (*SetField)(JRIEnv* env, jint op, void* a, jint b, void* c); - void (*SetFieldBoolean)(JRIEnv* env, jint op, void* a, jint b, jbool c); - void (*SetFieldByte)(JRIEnv* env, jint op, void* a, jint b, jbyte c); - void (*SetFieldChar)(JRIEnv* env, jint op, void* a, jint b, jchar c); - void (*SetFieldShort)(JRIEnv* env, jint op, void* a, jint b, jshort c); - void (*SetFieldInt)(JRIEnv* env, jint op, void* a, jint b, jint c); - void (*SetFieldLong)(JRIEnv* env, jint op, void* a, jint b, jlong c); - void (*SetFieldFloat)(JRIEnv* env, jint op, void* a, jint b, jfloat c); - void (*SetFieldDouble)(JRIEnv* env, jint op, void* a, jint b, jdouble c); - jbool (*IsSubclassOf)(JRIEnv* env, jint op, struct java_lang_Class* a, struct java_lang_Class* b); - jint (*GetStaticMethodID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); - void* (*CallStaticMethod)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - void* (*CallStaticMethodV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - void* (*CallStaticMethodA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jbool (*CallStaticMethodBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - jbool (*CallStaticMethodBooleanV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - jbool (*CallStaticMethodBooleanA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jbyte (*CallStaticMethodByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - jbyte (*CallStaticMethodByteV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - jbyte (*CallStaticMethodByteA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jchar (*CallStaticMethodChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - jchar (*CallStaticMethodCharV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - jchar (*CallStaticMethodCharA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jshort (*CallStaticMethodShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - jshort (*CallStaticMethodShortV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - jshort (*CallStaticMethodShortA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jint (*CallStaticMethodInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - jint (*CallStaticMethodIntV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - jint (*CallStaticMethodIntA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jlong (*CallStaticMethodLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - jlong (*CallStaticMethodLongV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - jlong (*CallStaticMethodLongA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jfloat (*CallStaticMethodFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - jfloat (*CallStaticMethodFloatV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - jfloat (*CallStaticMethodFloatA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jdouble (*CallStaticMethodDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, ...); - jdouble (*CallStaticMethodDoubleV)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, va_list c); - jdouble (*CallStaticMethodDoubleA)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, JRIValue* c); - jint (*GetStaticFieldID)(JRIEnv* env, jint op, struct java_lang_Class* a, const char* b, const char* c); - void* (*GetStaticField)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - jbool (*GetStaticFieldBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - jbyte (*GetStaticFieldByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - jchar (*GetStaticFieldChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - jshort (*GetStaticFieldShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - jint (*GetStaticFieldInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - jlong (*GetStaticFieldLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - jfloat (*GetStaticFieldFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - jdouble (*GetStaticFieldDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b); - void (*SetStaticField)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, void* c); - void (*SetStaticFieldBoolean)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jbool c); - void (*SetStaticFieldByte)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jbyte c); - void (*SetStaticFieldChar)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jchar c); - void (*SetStaticFieldShort)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jshort c); - void (*SetStaticFieldInt)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jint c); - void (*SetStaticFieldLong)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jlong c); - void (*SetStaticFieldFloat)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jfloat c); - void (*SetStaticFieldDouble)(JRIEnv* env, jint op, struct java_lang_Class* a, jint b, jdouble c); - struct java_lang_String* (*NewString)(JRIEnv* env, jint op, const jchar* a, jint b); - jint (*GetStringLength)(JRIEnv* env, jint op, struct java_lang_String* a); - const jchar* (*GetStringChars)(JRIEnv* env, jint op, struct java_lang_String* a); - struct java_lang_String* (*NewStringUTF)(JRIEnv* env, jint op, const jbyte* a, jint b); - jint (*GetStringUTFLength)(JRIEnv* env, jint op, struct java_lang_String* a); - const jbyte* (*GetStringUTFChars)(JRIEnv* env, jint op, struct java_lang_String* a); - void* (*NewScalarArray)(JRIEnv* env, jint op, jint a, const char* b, const jbyte* c); - jint (*GetScalarArrayLength)(JRIEnv* env, jint op, void* a); - jbyte* (*GetScalarArrayElements)(JRIEnv* env, jint op, void* a); - void* (*NewObjectArray)(JRIEnv* env, jint op, jint a, struct java_lang_Class* b, void* c); - jint (*GetObjectArrayLength)(JRIEnv* env, jint op, void* a); - void* (*GetObjectArrayElement)(JRIEnv* env, jint op, void* a, jint b); - void (*SetObjectArrayElement)(JRIEnv* env, jint op, void* a, jint b, void* c); - void (*RegisterNatives)(JRIEnv* env, jint op, struct java_lang_Class* a, char** b, void** c); - void (*UnregisterNatives)(JRIEnv* env, jint op, struct java_lang_Class* a); -}; - -/******************************************************************************* - * JRIEnv Operation IDs - ******************************************************************************/ - -typedef enum JRIEnvOperations { - JRI_Reserved0_op, - JRI_Reserved1_op, - JRI_Reserved2_op, - JRI_LoadClass_op, - JRI_FindClass_op, - JRI_Throw_op, - JRI_ThrowNew_op, - JRI_ExceptionOccurred_op, - JRI_ExceptionDescribe_op, - JRI_ExceptionClear_op, - JRI_NewGlobalRef_op, - JRI_DisposeGlobalRef_op, - JRI_GetGlobalRef_op, - JRI_SetGlobalRef_op, - JRI_IsSameObject_op, - JRI_NewObject_op, - JRI_NewObject_op_va_list, - JRI_NewObject_op_array, - JRI_GetObjectClass_op, - JRI_IsInstanceOf_op, - JRI_GetMethodID_op, - JRI_CallMethod_op, - JRI_CallMethod_op_va_list, - JRI_CallMethod_op_array, - JRI_CallMethodBoolean_op, - JRI_CallMethodBoolean_op_va_list, - JRI_CallMethodBoolean_op_array, - JRI_CallMethodByte_op, - JRI_CallMethodByte_op_va_list, - JRI_CallMethodByte_op_array, - JRI_CallMethodChar_op, - JRI_CallMethodChar_op_va_list, - JRI_CallMethodChar_op_array, - JRI_CallMethodShort_op, - JRI_CallMethodShort_op_va_list, - JRI_CallMethodShort_op_array, - JRI_CallMethodInt_op, - JRI_CallMethodInt_op_va_list, - JRI_CallMethodInt_op_array, - JRI_CallMethodLong_op, - JRI_CallMethodLong_op_va_list, - JRI_CallMethodLong_op_array, - JRI_CallMethodFloat_op, - JRI_CallMethodFloat_op_va_list, - JRI_CallMethodFloat_op_array, - JRI_CallMethodDouble_op, - JRI_CallMethodDouble_op_va_list, - JRI_CallMethodDouble_op_array, - JRI_GetFieldID_op, - JRI_GetField_op, - JRI_GetFieldBoolean_op, - JRI_GetFieldByte_op, - JRI_GetFieldChar_op, - JRI_GetFieldShort_op, - JRI_GetFieldInt_op, - JRI_GetFieldLong_op, - JRI_GetFieldFloat_op, - JRI_GetFieldDouble_op, - JRI_SetField_op, - JRI_SetFieldBoolean_op, - JRI_SetFieldByte_op, - JRI_SetFieldChar_op, - JRI_SetFieldShort_op, - JRI_SetFieldInt_op, - JRI_SetFieldLong_op, - JRI_SetFieldFloat_op, - JRI_SetFieldDouble_op, - JRI_IsSubclassOf_op, - JRI_GetStaticMethodID_op, - JRI_CallStaticMethod_op, - JRI_CallStaticMethod_op_va_list, - JRI_CallStaticMethod_op_array, - JRI_CallStaticMethodBoolean_op, - JRI_CallStaticMethodBoolean_op_va_list, - JRI_CallStaticMethodBoolean_op_array, - JRI_CallStaticMethodByte_op, - JRI_CallStaticMethodByte_op_va_list, - JRI_CallStaticMethodByte_op_array, - JRI_CallStaticMethodChar_op, - JRI_CallStaticMethodChar_op_va_list, - JRI_CallStaticMethodChar_op_array, - JRI_CallStaticMethodShort_op, - JRI_CallStaticMethodShort_op_va_list, - JRI_CallStaticMethodShort_op_array, - JRI_CallStaticMethodInt_op, - JRI_CallStaticMethodInt_op_va_list, - JRI_CallStaticMethodInt_op_array, - JRI_CallStaticMethodLong_op, - JRI_CallStaticMethodLong_op_va_list, - JRI_CallStaticMethodLong_op_array, - JRI_CallStaticMethodFloat_op, - JRI_CallStaticMethodFloat_op_va_list, - JRI_CallStaticMethodFloat_op_array, - JRI_CallStaticMethodDouble_op, - JRI_CallStaticMethodDouble_op_va_list, - JRI_CallStaticMethodDouble_op_array, - JRI_GetStaticFieldID_op, - JRI_GetStaticField_op, - JRI_GetStaticFieldBoolean_op, - JRI_GetStaticFieldByte_op, - JRI_GetStaticFieldChar_op, - JRI_GetStaticFieldShort_op, - JRI_GetStaticFieldInt_op, - JRI_GetStaticFieldLong_op, - JRI_GetStaticFieldFloat_op, - JRI_GetStaticFieldDouble_op, - JRI_SetStaticField_op, - JRI_SetStaticFieldBoolean_op, - JRI_SetStaticFieldByte_op, - JRI_SetStaticFieldChar_op, - JRI_SetStaticFieldShort_op, - JRI_SetStaticFieldInt_op, - JRI_SetStaticFieldLong_op, - JRI_SetStaticFieldFloat_op, - JRI_SetStaticFieldDouble_op, - JRI_NewString_op, - JRI_GetStringLength_op, - JRI_GetStringChars_op, - JRI_NewStringUTF_op, - JRI_GetStringUTFLength_op, - JRI_GetStringUTFChars_op, - JRI_NewScalarArray_op, - JRI_GetScalarArrayLength_op, - JRI_GetScalarArrayElements_op, - JRI_NewObjectArray_op, - JRI_GetObjectArrayLength_op, - JRI_GetObjectArrayElement_op, - JRI_SetObjectArrayElement_op, - JRI_RegisterNatives_op, - JRI_UnregisterNatives_op -} JRIEnvOperations; - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* __cplusplus */ - -#endif /* JRI_H */ -/******************************************************************************/ diff --git a/src/signer/npinclude/jri_md.h b/src/signer/npinclude/jri_md.h deleted file mode 100644 index 5ef37f2e..00000000 --- a/src/signer/npinclude/jri_md.h +++ /dev/null @@ -1,500 +0,0 @@ -/* -*- Mode: C; tab-width: 4; -*- */ -/******************************************************************************* - * Java Runtime Interface - Machine Dependent Types - * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. - ******************************************************************************/ - -#ifndef JRI_MD_H -#define JRI_MD_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/******************************************************************************* - * WHAT'S UP WITH THIS FILE? - * - * This is where we define the mystical JRI_PUBLIC_API macro that works on all - * platforms. If you're running with Visual C++, Symantec C, or Borland's - * development environment on the PC, you're all set. Or if you're on the Mac - * with Metrowerks, Symantec or MPW with SC you're ok too. For UNIX it shouldn't - * matter. - * - * On UNIX though you probably care about a couple of other symbols though: - * IS_LITTLE_ENDIAN must be defined for little-endian systems - * HAVE_LONG_LONG must be defined on systems that have 'long long' integers - * HAVE_ALIGNED_LONGLONGS must be defined if long-longs must be 8 byte aligned - * HAVE_ALIGNED_DOUBLES must be defined if doubles must be 8 byte aligned - * IS_64 must be defined on 64-bit machines (like Dec Alpha) - ******************************************************************************/ - -/* DLL Entry modifiers... */ - -/* PC */ -#if defined(XP_PC) || defined(_WINDOWS) || defined(WIN32) || defined(_WIN32) -# include -# if defined(_MSC_VER) -# if defined(WIN32) || defined(_WIN32) -# define JRI_PUBLIC_API(ResultType) _declspec(dllexport) ResultType -# define JRI_CALLBACK -# else /* !_WIN32 */ -# if defined(_WINDLL) -# define JRI_PUBLIC_API(ResultType) ResultType __cdecl __export __loadds -# define JRI_CALLBACK __loadds -# else /* !WINDLL */ -# define JRI_PUBLIC_API(ResultType) ResultType __cdecl __export -# define JRI_CALLBACK __export -# endif /* !WINDLL */ -# endif /* !_WIN32 */ -# elif defined(__BORLANDC__) -# if defined(WIN32) || defined(_WIN32) -# define JRI_PUBLIC_API(ResultType) __export ResultType -# define JRI_CALLBACK -# else /* !_WIN32 */ -# define JRI_PUBLIC_API(ResultType) ResultType _cdecl _export _loadds -# define JRI_CALLBACK _loadds -# endif -# else -# error Unsupported PC development environment. -# endif -# ifndef IS_LITTLE_ENDIAN -# define IS_LITTLE_ENDIAN -# endif - -/* Mac */ -#elif macintosh || Macintosh || THINK_C -# if defined(__MWERKS__) /* Metrowerks */ -# if !__option(enumsalwaysint) -# error You need to define 'Enums Always Int' for your project. -# endif -# if defined(GENERATING68K) && !GENERATINGCFM -# if !__option(fourbyteints) -# error You need to define 'Struct Alignment: 68k' for your project. -# endif -# endif /* !GENERATINGCFM */ -# elif defined(__SC__) /* Symantec */ -# error What are the Symantec defines? (warren@netscape.com) -# elif macintosh && applec /* MPW */ -# error Please upgrade to the latest MPW compiler (SC). -# else -# error Unsupported Mac development environment. -# endif -# define JRI_PUBLIC_API(ResultType) ResultType -# define JRI_CALLBACK - -/* Unix or else */ -#else -# define JRI_PUBLIC_API(ResultType) ResultType -# define JRI_CALLBACK -#endif - -#ifndef FAR /* for non-Win16 */ -#define FAR -#endif - -/******************************************************************************/ - -/* Java Scalar Types */ - -typedef unsigned char jbool; -typedef char jbyte; -typedef short jchar; -typedef short jshort; -#ifdef IS_64 /* XXX ok for alpha, but not right on all 64-bit architectures */ -typedef unsigned int juint; -typedef int jint; -#else -typedef unsigned long juint; -typedef long jint; -#endif -typedef float jfloat; -typedef double jdouble; - -typedef juint jsize; - -/******************************************************************************* - * jlong : long long (64-bit signed integer type) support. - ******************************************************************************/ - -/* -** Bit masking macros. (n must be <= 31 to be portable) -*/ -#define JRI_BIT(n) ((juint)1 << (n)) -#define JRI_BITMASK(n) (JRI_BIT(n) - 1) - -#ifdef HAVE_LONG_LONG - -#if !(defined(WIN32) || defined(_WIN32)) -typedef long long jlong; -typedef unsigned long long julong; - -#define jlong_MAXINT 0x7fffffffffffffffLL -#define jlong_MININT 0x8000000000000000LL -#define jlong_ZERO 0x0LL - -#else -typedef LONGLONG jlong; -typedef DWORDLONG julong; - -#define jlong_MAXINT 0x7fffffffffffffffi64 -#define jlong_MININT 0x8000000000000000i64 -#define jlong_ZERO 0x0i64 - -#endif - -#define jlong_IS_ZERO(a) ((a) == 0) -#define jlong_EQ(a, b) ((a) == (b)) -#define jlong_NE(a, b) ((a) != (b)) -#define jlong_GE_ZERO(a) ((a) >= 0) -#define jlong_CMP(a, op, b) ((a) op (b)) - -#define jlong_AND(r, a, b) ((r) = (a) & (b)) -#define jlong_OR(r, a, b) ((r) = (a) | (b)) -#define jlong_XOR(r, a, b) ((r) = (a) ^ (b)) -#define jlong_OR2(r, a) ((r) = (r) | (a)) -#define jlong_NOT(r, a) ((r) = ~(a)) - -#define jlong_NEG(r, a) ((r) = -(a)) -#define jlong_ADD(r, a, b) ((r) = (a) + (b)) -#define jlong_SUB(r, a, b) ((r) = (a) - (b)) - -#define jlong_MUL(r, a, b) ((r) = (a) * (b)) -#define jlong_DIV(r, a, b) ((r) = (a) / (b)) -#define jlong_MOD(r, a, b) ((r) = (a) % (b)) - -#define jlong_SHL(r, a, b) ((r) = (a) << (b)) -#define jlong_SHR(r, a, b) ((r) = (a) >> (b)) -#define jlong_USHR(r, a, b) ((r) = (julong)(a) >> (b)) -#define jlong_ISHL(r, a, b) ((r) = ((jlong)(a)) << (b)) - -#define jlong_L2I(i, l) ((i) = (int)(l)) -#define jlong_L2UI(ui, l) ((ui) =(unsigned int)(l)) -#define jlong_L2F(f, l) ((f) = (l)) -#define jlong_L2D(d, l) ((d) = (l)) - -#define jlong_I2L(l, i) ((l) = (i)) -#define jlong_UI2L(l, ui) ((l) = (ui)) -#define jlong_F2L(l, f) ((l) = (f)) -#define jlong_D2L(l, d) ((l) = (d)) - -#define jlong_UDIVMOD(qp, rp, a, b) \ - (*(qp) = ((julong)(a) / (b)), \ - *(rp) = ((julong)(a) % (b))) - -#else /* !HAVE_LONG_LONG */ - -typedef struct { -#ifdef IS_LITTLE_ENDIAN - juint lo, hi; -#else - juint hi, lo; -#endif -} jlong; -typedef jlong julong; - -extern jlong jlong_MAXINT, jlong_MININT, jlong_ZERO; - -#define jlong_IS_ZERO(a) (((a).hi == 0) && ((a).lo == 0)) -#define jlong_EQ(a, b) (((a).hi == (b).hi) && ((a).lo == (b).lo)) -#define jlong_NE(a, b) (((a).hi != (b).hi) || ((a).lo != (b).lo)) -#define jlong_GE_ZERO(a) (((a).hi >> 31) == 0) - -/* - * NB: jlong_CMP and jlong_UCMP work only for strict relationals (<, >). - */ -#define jlong_CMP(a, op, b) (((int32)(a).hi op (int32)(b).hi) || \ - (((a).hi == (b).hi) && ((a).lo op (b).lo))) -#define jlong_UCMP(a, op, b) (((a).hi op (b).hi) || \ - (((a).hi == (b).hi) && ((a).lo op (b).lo))) - -#define jlong_AND(r, a, b) ((r).lo = (a).lo & (b).lo, \ - (r).hi = (a).hi & (b).hi) -#define jlong_OR(r, a, b) ((r).lo = (a).lo | (b).lo, \ - (r).hi = (a).hi | (b).hi) -#define jlong_XOR(r, a, b) ((r).lo = (a).lo ^ (b).lo, \ - (r).hi = (a).hi ^ (b).hi) -#define jlong_OR2(r, a) ((r).lo = (r).lo | (a).lo, \ - (r).hi = (r).hi | (a).hi) -#define jlong_NOT(r, a) ((r).lo = ~(a).lo, \ - (r).hi = ~(a).hi) - -#define jlong_NEG(r, a) ((r).lo = -(int32)(a).lo, \ - (r).hi = -(int32)(a).hi - ((r).lo != 0)) -#define jlong_ADD(r, a, b) { \ - jlong _a, _b; \ - _a = a; _b = b; \ - (r).lo = _a.lo + _b.lo; \ - (r).hi = _a.hi + _b.hi + ((r).lo < _b.lo); \ -} - -#define jlong_SUB(r, a, b) { \ - jlong _a, _b; \ - _a = a; _b = b; \ - (r).lo = _a.lo - _b.lo; \ - (r).hi = _a.hi - _b.hi - (_a.lo < _b.lo); \ -} \ - -/* - * Multiply 64-bit operands a and b to get 64-bit result r. - * First multiply the low 32 bits of a and b to get a 64-bit result in r. - * Then add the outer and inner products to r.hi. - */ -#define jlong_MUL(r, a, b) { \ - jlong _a, _b; \ - _a = a; _b = b; \ - jlong_MUL32(r, _a.lo, _b.lo); \ - (r).hi += _a.hi * _b.lo + _a.lo * _b.hi; \ -} - -/* XXX _jlong_lo16(a) = ((a) << 16 >> 16) is better on some archs (not on mips) */ -#define _jlong_lo16(a) ((a) & JRI_BITMASK(16)) -#define _jlong_hi16(a) ((a) >> 16) - -/* - * Multiply 32-bit operands a and b to get 64-bit result r. - * Use polynomial expansion based on primitive field element (1 << 16). - */ -#define jlong_MUL32(r, a, b) { \ - juint _a1, _a0, _b1, _b0, _y0, _y1, _y2, _y3; \ - _a1 = _jlong_hi16(a), _a0 = _jlong_lo16(a); \ - _b1 = _jlong_hi16(b), _b0 = _jlong_lo16(b); \ - _y0 = _a0 * _b0; \ - _y1 = _a0 * _b1; \ - _y2 = _a1 * _b0; \ - _y3 = _a1 * _b1; \ - _y1 += _jlong_hi16(_y0); /* can't carry */ \ - _y1 += _y2; /* might carry */ \ - if (_y1 < _y2) _y3 += 1 << 16; /* propagate */ \ - (r).lo = (_jlong_lo16(_y1) << 16) + _jlong_lo16(_y0); \ - (r).hi = _y3 + _jlong_hi16(_y1); \ -} - -/* - * Divide 64-bit unsigned operand a by 64-bit unsigned operand b, setting *qp - * to the 64-bit unsigned quotient, and *rp to the 64-bit unsigned remainder. - * Minimize effort if one of qp and rp is null. - */ -#define jlong_UDIVMOD(qp, rp, a, b) jlong_udivmod(qp, rp, a, b) - -extern JRI_PUBLIC_API(void) -jlong_udivmod(julong *qp, julong *rp, julong a, julong b); - -#define jlong_DIV(r, a, b) { \ - jlong _a, _b; \ - juint _negative = (int32)(a).hi < 0; \ - if (_negative) { \ - jlong_NEG(_a, a); \ - } else { \ - _a = a; \ - } \ - if ((int32)(b).hi < 0) { \ - _negative ^= 1; \ - jlong_NEG(_b, b); \ - } else { \ - _b = b; \ - } \ - jlong_UDIVMOD(&(r), 0, _a, _b); \ - if (_negative) \ - jlong_NEG(r, r); \ -} - -#define jlong_MOD(r, a, b) { \ - jlong _a, _b; \ - juint _negative = (int32)(a).hi < 0; \ - if (_negative) { \ - jlong_NEG(_a, a); \ - } else { \ - _a = a; \ - } \ - if ((int32)(b).hi < 0) { \ - jlong_NEG(_b, b); \ - } else { \ - _b = b; \ - } \ - jlong_UDIVMOD(0, &(r), _a, _b); \ - if (_negative) \ - jlong_NEG(r, r); \ -} - -/* - * NB: b is a juint, not jlong or julong, for the shift ops. - */ -#define jlong_SHL(r, a, b) { \ - if (b) { \ - jlong _a; \ - _a = a; \ - if ((b) < 32) { \ - (r).lo = _a.lo << (b); \ - (r).hi = (_a.hi << (b)) | (_a.lo >> (32 - (b))); \ - } else { \ - (r).lo = 0; \ - (r).hi = _a.lo << ((b) & 31); \ - } \ - } else { \ - (r) = (a); \ - } \ -} - -/* a is an int32, b is int32, r is jlong */ -#define jlong_ISHL(r, a, b) { \ - if (b) { \ - jlong _a; \ - _a.lo = (a); \ - _a.hi = 0; \ - if ((b) < 32) { \ - (r).lo = (a) << (b); \ - (r).hi = ((a) >> (32 - (b))); \ - } else { \ - (r).lo = 0; \ - (r).hi = (a) << ((b) & 31); \ - } \ - } else { \ - (r).lo = (a); \ - (r).hi = 0; \ - } \ -} - -#define jlong_SHR(r, a, b) { \ - if (b) { \ - jlong _a; \ - _a = a; \ - if ((b) < 32) { \ - (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> (b)); \ - (r).hi = (int32)_a.hi >> (b); \ - } else { \ - (r).lo = (int32)_a.hi >> ((b) & 31); \ - (r).hi = (int32)_a.hi >> 31; \ - } \ - } else { \ - (r) = (a); \ - } \ -} - -#define jlong_USHR(r, a, b) { \ - if (b) { \ - jlong _a; \ - _a = a; \ - if ((b) < 32) { \ - (r).lo = (_a.hi << (32 - (b))) | (_a.lo >> (b)); \ - (r).hi = _a.hi >> (b); \ - } else { \ - (r).lo = _a.hi >> ((b) & 31); \ - (r).hi = 0; \ - } \ - } else { \ - (r) = (a); \ - } \ -} - -#define jlong_L2I(i, l) ((i) = (l).lo) -#define jlong_L2UI(ui, l) ((ui) = (l).lo) -#define jlong_L2F(f, l) { double _d; jlong_L2D(_d, l); (f) = (float) _d; } - -#define jlong_L2D(d, l) { \ - int32 _negative; \ - jlong _absval; \ - \ - _negative = (l).hi >> 31; \ - if (_negative) { \ - jlong_NEG(_absval, l); \ - } else { \ - _absval = l; \ - } \ - (d) = (double)_absval.hi * 4.294967296e9 + _absval.lo; \ - if (_negative) \ - (d) = -(d); \ -} - -#define jlong_I2L(l, i) ((l).hi = (i) >> 31, (l).lo = (i)) -#define jlong_UI2L(l, ui) ((l).hi = 0, (l).lo = (ui)) -#define jlong_F2L(l, f) { double _d = (double) f; jlong_D2L(l, _d); } - -#define jlong_D2L(l, d) { \ - int _negative; \ - double _absval, _d_hi; \ - jlong _lo_d; \ - \ - _negative = ((d) < 0); \ - _absval = _negative ? -(d) : (d); \ - \ - (l).hi = (juint)(_absval / 4.294967296e9); \ - (l).lo = 0; \ - jlong_L2D(_d_hi, l); \ - _absval -= _d_hi; \ - _lo_d.hi = 0; \ - if (_absval < 0) { \ - _lo_d.lo = (juint) -_absval; \ - jlong_SUB(l, l, _lo_d); \ - } else { \ - _lo_d.lo = (juint) _absval; \ - jlong_ADD(l, l, _lo_d); \ - } \ - \ - if (_negative) \ - jlong_NEG(l, l); \ -} - -#endif /* !HAVE_LONG_LONG */ - -/******************************************************************************/ -/* -** JDK Stuff -- This stuff is still needed while we're using the JDK -** dynamic linking strategy to call native methods. -*/ - -typedef union JRI_JDK_stack_item { - /* Non pointer items */ - jint i; - jfloat f; - jint o; - /* Pointer items */ - void *h; - void *p; - unsigned char *addr; -#ifdef IS_64 - double d; - long l; /* == 64bits! */ -#endif -} JRI_JDK_stack_item; - -typedef union JRI_JDK_Java8Str { - jint x[2]; - jdouble d; - jlong l; - void *p; - float f; -} JRI_JDK_Java8; - -#ifdef HAVE_ALIGNED_LONGLONGS -#define JRI_GET_INT64(_t,_addr) ( ((_t).x[0] = ((jint*)(_addr))[0]), \ - ((_t).x[1] = ((jint*)(_addr))[1]), \ - (_t).l ) -#define JRI_SET_INT64(_t, _addr, _v) ( (_t).l = (_v), \ - ((jint*)(_addr))[0] = (_t).x[0], \ - ((jint*)(_addr))[1] = (_t).x[1] ) -#else -#define JRI_GET_INT64(_t,_addr) (*(jlong*)(_addr)) -#define JRI_SET_INT64(_t, _addr, _v) (*(jlong*)(_addr) = (_v)) -#endif - -/* If double's must be aligned on doubleword boundaries then define this */ -#ifdef HAVE_ALIGNED_DOUBLES -#define JRI_GET_DOUBLE(_t,_addr) ( ((_t).x[0] = ((jint*)(_addr))[0]), \ - ((_t).x[1] = ((jint*)(_addr))[1]), \ - (_t).d ) -#define JRI_SET_DOUBLE(_t, _addr, _v) ( (_t).d = (_v), \ - ((jint*)(_addr))[0] = (_t).x[0], \ - ((jint*)(_addr))[1] = (_t).x[1] ) -#else -#define JRI_GET_DOUBLE(_t,_addr) (*(jdouble*)(_addr)) -#define JRI_SET_DOUBLE(_t, _addr, _v) (*(jdouble*)(_addr) = (_v)) -#endif - -/******************************************************************************/ -#ifdef __cplusplus -} -#endif -#endif /* JRI_MD_H */ -/******************************************************************************/ diff --git a/src/signer/npinclude/jritypes.h b/src/signer/npinclude/jritypes.h deleted file mode 100644 index fad21c70..00000000 --- a/src/signer/npinclude/jritypes.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -*- Mode: C; tab-width: 4; -*- */ -/******************************************************************************* - * Java Runtime Interface - * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. - ******************************************************************************/ - -#ifndef JRITYPES_H -#define JRITYPES_H - -#include "jri_md.h" -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/******************************************************************************* - * Types - ******************************************************************************/ - -struct JRIEnvInterface; - -typedef void* JRIRef; -typedef void* JRIGlobalRef; - -typedef jint JRIInterfaceID[4]; -typedef jint JRIFieldID; -typedef jint JRIMethodID; - -/* synonyms: */ -typedef JRIGlobalRef jglobal; -typedef JRIRef jref; - -typedef union JRIValue { - jbool z; - jbyte b; - jchar c; - jshort s; - jint i; - jlong l; - jfloat f; - jdouble d; - jref r; -} JRIValue; - -typedef JRIValue jvalue; - -typedef enum JRIBoolean { - JRIFalse = 0, - JRITrue = 1 -} JRIBoolean; - -typedef enum JRIConstant { - JRIUninitialized = -1 -} JRIConstant; - -/* convenience types: */ -typedef JRIRef jbooleanArray; -typedef JRIRef jbyteArray; -typedef JRIRef jcharArray; -typedef JRIRef jshortArray; -typedef JRIRef jintArray; -typedef JRIRef jlongArray; -typedef JRIRef jfloatArray; -typedef JRIRef jdoubleArray; -typedef JRIRef jobjectArray; -typedef JRIRef jstringArray; -typedef JRIRef jarrayArray; - -#define JRIConstructorMethodName "" - -/******************************************************************************* - * Signature Construction Macros - ******************************************************************************/ - -/* -** These macros can be used to construct signature strings. Hopefully their names -** are a little easier to remember than the single character they correspond to. -** For example, to specify the signature of the method: -** -** public int read(byte b[], int off, int len); -** -** you could write something like this in C: -** -** char* readSig = JRISigMethod(JRISigArray(JRISigByte) -** JRISigInt -** JRISigInt) JRISigInt; -** -** Of course, don't put commas between the types. -*/ -#define JRISigArray(T) "[" T -#define JRISigByte "B" -#define JRISigChar "C" -#define JRISigClass(name) "L" name ";" -#define JRISigFloat "F" -#define JRISigDouble "D" -#define JRISigMethod(args) "(" args ")" -#define JRISigNoArgs "" -#define JRISigInt "I" -#define JRISigLong "J" -#define JRISigShort "S" -#define JRISigVoid "V" -#define JRISigBoolean "Z" - -/******************************************************************************* - * Environments - ******************************************************************************/ - -extern JRI_PUBLIC_API(const struct JRIEnvInterface**) -JRI_GetCurrentEnv(void); - -/******************************************************************************* - * Specific Scalar Array Types - ******************************************************************************/ - -/* -** The JRI Native Method Interface does not support boolean arrays. This -** is to allow Java runtime implementations to optimize boolean array -** storage. Using the ScalarArray operations on boolean arrays is bound -** to fail, so convert any boolean arrays to byte arrays in Java before -** passing them to a native method. -*/ - -#define JRI_NewByteArray(env, length, initialValues) \ - JRI_NewScalarArray(env, length, JRISigByte, (jbyte*)(initialValues)) -#define JRI_GetByteArrayLength(env, array) \ - JRI_GetScalarArrayLength(env, array) -#define JRI_GetByteArrayElements(env, array) \ - JRI_GetScalarArrayElements(env, array) - -#define JRI_NewCharArray(env, length, initialValues) \ - JRI_NewScalarArray(env, ((length) * sizeof(jchar)), JRISigChar, (jbyte*)(initialValues)) -#define JRI_GetCharArrayLength(env, array) \ - JRI_GetScalarArrayLength(env, array) -#define JRI_GetCharArrayElements(env, array) \ - ((jchar*)JRI_GetScalarArrayElements(env, array)) - -#define JRI_NewShortArray(env, length, initialValues) \ - JRI_NewScalarArray(env, ((length) * sizeof(jshort)), JRISigShort, (jbyte*)(initialValues)) -#define JRI_GetShortArrayLength(env, array) \ - JRI_GetScalarArrayLength(env, array) -#define JRI_GetShortArrayElements(env, array) \ - ((jshort*)JRI_GetScalarArrayElements(env, array)) - -#define JRI_NewIntArray(env, length, initialValues) \ - JRI_NewScalarArray(env, ((length) * sizeof(jint)), JRISigInt, (jbyte*)(initialValues)) -#define JRI_GetIntArrayLength(env, array) \ - JRI_GetScalarArrayLength(env, array) -#define JRI_GetIntArrayElements(env, array) \ - ((jint*)JRI_GetScalarArrayElements(env, array)) - -#define JRI_NewLongArray(env, length, initialValues) \ - JRI_NewScalarArray(env, ((length) * sizeof(jlong)), JRISigLong, (jbyte*)(initialValues)) -#define JRI_GetLongArrayLength(env, array) \ - JRI_GetScalarArrayLength(env, array) -#define JRI_GetLongArrayElements(env, array) \ - ((jlong*)JRI_GetScalarArrayElements(env, array)) - -#define JRI_NewFloatArray(env, length, initialValues) \ - JRI_NewScalarArray(env, ((length) * sizeof(jfloat)), JRISigFloat, (jbyte*)(initialValues)) -#define JRI_GetFloatArrayLength(env, array) \ - JRI_GetScalarArrayLength(env, array) -#define JRI_GetFloatArrayElements(env, array) \ - ((jfloat*)JRI_GetScalarArrayElements(env, array)) - -#define JRI_NewDoubleArray(env, length, initialValues) \ - JRI_NewScalarArray(env, ((length) * sizeof(jdouble)), JRISigDouble, (jbyte*)(initialValues)) -#define JRI_GetDoubleArrayLength(env, array) \ - JRI_GetScalarArrayLength(env, array) -#define JRI_GetDoubleArrayElements(env, array) \ - ((jdouble*)JRI_GetScalarArrayElements(env, array)) - -/******************************************************************************/ -#ifdef __cplusplus -} -#endif -#endif /* JRITYPES_H */ -/******************************************************************************/ diff --git a/src/signer/npinclude/npapi.h b/src/signer/npinclude/npapi.h deleted file mode 100644 index f77cc015..00000000 --- a/src/signer/npinclude/npapi.h +++ /dev/null @@ -1,396 +0,0 @@ -/* -*- Mode: C; tab-width: 4; -*- */ -/* - * npapi.h $Revision$ - * Netscape client plug-in API spec - */ - -#ifndef _NPAPI_H_ -#define _NPAPI_H_ - -#include "jri.h" /* Java Runtime Interface */ - - -/* XXX this needs to get out of here */ -#if defined(__MWERKS__) -#ifndef XP_MAC -#define XP_MAC -#endif -#endif - - - -/*----------------------------------------------------------------------*/ -/* Plugin Version Constants */ -/*----------------------------------------------------------------------*/ - -#define NP_VERSION_MAJOR 0 -#define NP_VERSION_MINOR 9 - - -#if defined(_AIX) -#define _INT16 -#define _INT32 -#endif - -/*----------------------------------------------------------------------*/ -/* Definition of Basic Types */ -/*----------------------------------------------------------------------*/ - -#ifndef _UINT16 -typedef unsigned short uint16; -#endif -#ifndef _UINT32 -#if defined(__alpha) -typedef unsigned int uint32; -#else /* __alpha */ -typedef unsigned long uint32; -#endif /* __alpha */ -#endif -#ifndef _INT16 -typedef short int16; -#endif -#ifndef _INT32 -#if defined(__alpha) -typedef int int32; -#else /* __alpha */ -typedef long int32; -#endif /* __alpha */ -#endif - -#ifndef FALSE -#define FALSE (0) -#endif -#ifndef TRUE -#define TRUE (1) -#endif -#ifndef NULL -#define NULL (0L) -#endif - -typedef unsigned char NPBool; -typedef void* NPEvent; -typedef int16 NPError; -typedef int16 NPReason; -typedef char* NPMIMEType; - - - -/*----------------------------------------------------------------------*/ -/* Structures and definitions */ -/*----------------------------------------------------------------------*/ - -/* - * NPP is a plug-in's opaque instance handle - */ -typedef struct _NPP -{ - void* pdata; /* plug-in private data */ - void* ndata; /* netscape private data */ -} NPP_t; - -typedef NPP_t* NPP; - - -typedef struct _NPStream -{ - void* pdata; /* plug-in private data */ - void* ndata; /* netscape private data */ - const char* url; - uint32 end; - uint32 lastmodified; - void* notifyData; -} NPStream; - - -typedef struct _NPByteRange -{ - int32 offset; /* negative offset means from the end */ - uint32 length; - struct _NPByteRange* next; -} NPByteRange; - - -typedef struct _NPSavedData -{ - int32 len; - void* buf; -} NPSavedData; - - -typedef struct _NPRect -{ - uint16 top; - uint16 left; - uint16 bottom; - uint16 right; -} NPRect; - - -#ifdef XP_UNIX -/* - * Unix specific structures and definitions - */ -#include - -/* - * Callback Structures. - * - * These are used to pass additional platform specific information. - */ -enum { - NP_SETWINDOW = 1 -}; - -typedef struct -{ - int32 type; -} NPAnyCallbackStruct; - -typedef struct -{ - int32 type; - Display* display; - Visual* visual; - Colormap colormap; - unsigned int depth; -} NPSetWindowCallbackStruct; - -/* - * List of variable names for which NPP_GetValue shall be implemented - */ -typedef enum { - NPPVpluginNameString = 1, - NPPVpluginDescriptionString -} NPPVariable; - -/* - * List of variable names for which NPN_GetValue is implemented by Mozilla - */ -typedef enum { - NPNVxDisplay = 1, - NPNVxtAppContext -} NPNVariable; - -#endif /* XP_UNIX */ - - -typedef struct _NPWindow -{ - void* window; /* Platform specific window handle */ - uint32 x; /* Position of top left corner relative */ - uint32 y; /* to a netscape page. */ - uint32 width; /* Maximum window size */ - uint32 height; - NPRect clipRect; /* Clipping rectangle in port coordinates */ - /* Used by MAC only. */ -#ifdef XP_UNIX - void * ws_info; /* Platform-dependent additonal data */ -#endif /* XP_UNIX */ -} NPWindow; - - -typedef struct _NPFullPrint -{ - NPBool pluginPrinted; /* Set TRUE if plugin handled fullscreen */ - /* printing */ - NPBool printOne; /* TRUE if plugin should print one copy */ - /* to default printer */ - void* platformPrint; /* Platform-specific printing info */ -} NPFullPrint; - -typedef struct _NPEmbedPrint -{ - NPWindow window; - void* platformPrint; /* Platform-specific printing info */ -} NPEmbedPrint; - -typedef struct _NPPrint -{ - uint16 mode; /* NP_FULL or NP_EMBED */ - union - { - NPFullPrint fullPrint; /* if mode is NP_FULL */ - NPEmbedPrint embedPrint; /* if mode is NP_EMBED */ - } print; -} NPPrint; - - -#ifdef XP_MAC -/* - * Mac-specific structures and definitions. - */ - -#include -#include - -typedef struct NP_Port -{ - CGrafPtr port; /* Grafport */ - int32 portx; /* position inside the topmost window */ - int32 porty; -} NP_Port; - -/* - * Non-standard event types that can be passed to HandleEvent - */ -#define getFocusEvent (osEvt + 16) -#define loseFocusEvent (osEvt + 17) -#define adjustCursorEvent (osEvt + 18) - -#endif /* XP_MAC */ - - -/* - * Values for mode passed to NPP_New: - */ -#define NP_EMBED 1 -#define NP_FULL 2 - -/* - * Values for stream type passed to NPP_NewStream: - */ -#define NP_NORMAL 1 -#define NP_SEEK 2 -#define NP_ASFILE 3 -#define NP_ASFILEONLY 4 - -#define NP_MAXREADY (((unsigned)(~0)<<1)>>1) - - - -/*----------------------------------------------------------------------*/ -/* Error and Reason Code definitions */ -/*----------------------------------------------------------------------*/ - -/* - * Values of type NPError: - */ -#define NPERR_BASE 0 -#define NPERR_NO_ERROR (NPERR_BASE + 0) -#define NPERR_GENERIC_ERROR (NPERR_BASE + 1) -#define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2) -#define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3) -#define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4) -#define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5) -#define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6) -#define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7) -#define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8) -#define NPERR_INVALID_PARAM (NPERR_BASE + 9) -#define NPERR_INVALID_URL (NPERR_BASE + 10) -#define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11) -#define NPERR_NO_DATA (NPERR_BASE + 12) -#define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13) - -/* - * Values of type NPReason: - */ -#define NPRES_BASE 0 -#define NPRES_DONE (NPRES_BASE + 0) -#define NPRES_NETWORK_ERR (NPRES_BASE + 1) -#define NPRES_USER_BREAK (NPRES_BASE + 2) - -/* - * Don't use these obsolete error codes any more. - */ -#define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR -#define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR -#define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK - -/* - * Version feature information - */ -#define NPVERS_HAS_STREAMOUTPUT 8 -#define NPVERS_HAS_NOTIFICATION 9 -#define NPVERS_HAS_LIVECONNECT 9 - - -/*----------------------------------------------------------------------*/ -/* Function Prototypes */ -/*----------------------------------------------------------------------*/ - -#if defined(_WINDOWS) && !defined(WIN32) -#define NP_LOADDS _loadds -#else -#define NP_LOADDS -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * NPP_* functions are provided by the plugin and called by the navigator. - */ - -#ifdef XP_UNIX -char* NPP_GetMIMEDescription(void); -NPError NPP_GetValue(void *instance, NPPVariable variable, - void *value); -#endif /* XP_UNIX */ -NPError NPP_Initialize(void); -void NPP_Shutdown(void); -NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, - uint16 mode, int16 argc, char* argn[], - char* argv[], NPSavedData* saved); -NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save); -NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window); -NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type, - NPStream* stream, NPBool seekable, - uint16* stype); -NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream, - NPReason reason); -int32 NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream); -int32 NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32 offset, - int32 len, void* buffer); -void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream, - const char* fname); -void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint); -int16 NPP_HandleEvent(NPP instance, void* event); -void NPP_URLNotify(NPP instance, const char* url, - NPReason reason, void* notifyData); -jref NPP_GetJavaClass(void); - - -/* - * NPN_* functions are provided by the navigator and called by the plugin. - */ - -#ifdef XP_UNIX -NPError NPN_GetValue(NPP instance, NPNVariable variable, - void *value); -#endif /* XP_UNIX */ -void NPN_Version(int* plugin_major, int* plugin_minor, - int* netscape_major, int* netscape_minor); -NPError NPN_GetURLNotify(NPP instance, const char* url, - const char* target, void* notifyData); -NPError NPN_GetURL(NPP instance, const char* url, - const char* target); -NPError NPN_PostURLNotify(NPP instance, const char* url, - const char* target, uint32 len, - const char* buf, NPBool file, - void* notifyData); -NPError NPN_PostURL(NPP instance, const char* url, - const char* target, uint32 len, - const char* buf, NPBool file); -NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList); -NPError NPN_NewStream(NPP instance, NPMIMEType type, - const char* target, NPStream** stream); -int32 NPN_Write(NPP instance, NPStream* stream, int32 len, - void* buffer); -NPError NPN_DestroyStream(NPP instance, NPStream* stream, - NPReason reason); -void NPN_Status(NPP instance, const char* message); -const char* NPN_UserAgent(NPP instance); -void* NPN_MemAlloc(uint32 size); -void NPN_MemFree(void* ptr); -uint32 NPN_MemFlush(uint32 size); -void NPN_ReloadPlugins(NPBool reloadPages); -JRIEnv* NPN_GetJavaEnv(void); -jref NPN_GetJavaPeer(NPP instance); - - -#ifdef __cplusplus -} /* end extern "C" */ -#endif - -#endif /* _NPAPI_H_ */ diff --git a/src/signer/npinclude/npunix.c b/src/signer/npinclude/npunix.c deleted file mode 100644 index 1c742d6d..00000000 --- a/src/signer/npinclude/npunix.c +++ /dev/null @@ -1,406 +0,0 @@ -/* - * npunix.c - * - * Netscape Client Plugin API - * - Wrapper function to interface with the Netscape Navigator - * - * dp Suresh - * - *---------------------------------------------------------------------- - * PLUGIN DEVELOPERS: - * YOU WILL NOT NEED TO EDIT THIS FILE. - *---------------------------------------------------------------------- - */ - -#define XP_UNIX 1 - -#include -#include "npapi.h" -#include "npupp.h" - -/* - * Define PLUGIN_TRACE to have the wrapper functions print - * messages to stderr whenever they are called. - */ - -#ifdef PLUGIN_TRACE -#include -#define PLUGINDEBUGSTR(msg) fprintf(stderr, "%s\n", msg) -#else -#define PLUGINDEBUGSTR(msg) -#endif - - -/*********************************************************************** - * - * Globals - * - ***********************************************************************/ - -static NPNetscapeFuncs gNetscapeFuncs; /* Netscape Function table */ - - -/*********************************************************************** - * - * Wrapper functions : plugin calling Netscape Navigator - * - * These functions let the plugin developer just call the APIs - * as documented and defined in npapi.h, without needing to know - * about the function table and call macros in npupp.h. - * - ***********************************************************************/ - -void -NPN_Version(int* plugin_major, int* plugin_minor, - int* netscape_major, int* netscape_minor) -{ - *plugin_major = NP_VERSION_MAJOR; - *plugin_minor = NP_VERSION_MINOR; - - /* Major version is in high byte */ - *netscape_major = gNetscapeFuncs.version >> 8; - /* Minor version is in low byte */ - *netscape_minor = gNetscapeFuncs.version & 0xFF; -} - -NPError -NPN_GetValue(NPP instance, NPNVariable variable, void *r_value) -{ - return CallNPN_GetValueProc(gNetscapeFuncs.getvalue, - instance, variable, r_value); -} - -NPError -NPN_GetURL(NPP instance, const char* url, const char* window) -{ - return CallNPN_GetURLProc(gNetscapeFuncs.geturl, instance, url, window); -} - -NPError -NPN_PostURL(NPP instance, const char* url, const char* window, - uint32 len, const char* buf, NPBool file) -{ - return CallNPN_PostURLProc(gNetscapeFuncs.posturl, instance, - url, window, len, buf, file); -} - -NPError -NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) -{ - return CallNPN_RequestReadProc(gNetscapeFuncs.requestread, - stream, rangeList); -} - -NPError -NPN_NewStream(NPP instance, NPMIMEType type, const char *window, - NPStream** stream_ptr) -{ - return CallNPN_NewStreamProc(gNetscapeFuncs.newstream, instance, - type, window, stream_ptr); -} - -int32 -NPN_Write(NPP instance, NPStream* stream, int32 len, void* buffer) -{ - return CallNPN_WriteProc(gNetscapeFuncs.write, instance, - stream, len, buffer); -} - -NPError -NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) -{ - return CallNPN_DestroyStreamProc(gNetscapeFuncs.destroystream, - instance, stream, reason); -} - -void -NPN_Status(NPP instance, const char* message) -{ - CallNPN_StatusProc(gNetscapeFuncs.status, instance, message); -} - -const char* -NPN_UserAgent(NPP instance) -{ - return CallNPN_UserAgentProc(gNetscapeFuncs.uagent, instance); -} - -void* -NPN_MemAlloc(uint32 size) -{ - return CallNPN_MemAllocProc(gNetscapeFuncs.memalloc, size); -} - -void NPN_MemFree(void* ptr) -{ - CallNPN_MemFreeProc(gNetscapeFuncs.memfree, ptr); -} - -uint32 NPN_MemFlush(uint32 size) -{ - return CallNPN_MemFlushProc(gNetscapeFuncs.memflush, size); -} - -void NPN_ReloadPlugins(NPBool reloadPages) -{ - CallNPN_ReloadPluginsProc(gNetscapeFuncs.reloadplugins, reloadPages); -} - -JRIEnv* NPN_GetJavaEnv() -{ - return CallNPN_GetJavaEnvProc(gNetscapeFuncs.getJavaEnv); -} - -jref NPN_GetJavaPeer(NPP instance) -{ - return CallNPN_GetJavaPeerProc(gNetscapeFuncs.getJavaPeer, - instance); -} - - -/*********************************************************************** - * - * Wrapper functions : Netscape Navigator -> plugin - * - * These functions let the plugin developer just create the APIs - * as documented and defined in npapi.h, without needing to - * install those functions in the function table or worry about - * setting up globals for 68K plugins. - * - ***********************************************************************/ - -NPError -Private_New(NPMIMEType pluginType, NPP instance, uint16 mode, - int16 argc, char* argn[], char* argv[], NPSavedData* saved) -{ - NPError ret; - PLUGINDEBUGSTR("New"); - ret = NPP_New(pluginType, instance, mode, argc, argn, argv, saved); - return ret; -} - -NPError -Private_Destroy(NPP instance, NPSavedData** save) -{ - PLUGINDEBUGSTR("Destroy"); - return NPP_Destroy(instance, save); -} - -NPError -Private_SetWindow(NPP instance, NPWindow* window) -{ - NPError err; - PLUGINDEBUGSTR("SetWindow"); - err = NPP_SetWindow(instance, window); - return err; -} - -NPError -Private_NewStream(NPP instance, NPMIMEType type, NPStream* stream, - NPBool seekable, uint16* stype) -{ - NPError err; - PLUGINDEBUGSTR("NewStream"); - err = NPP_NewStream(instance, type, stream, seekable, stype); - return err; -} - -int32 -Private_WriteReady(NPP instance, NPStream* stream) -{ - unsigned int result; - PLUGINDEBUGSTR("WriteReady"); - result = NPP_WriteReady(instance, stream); - return result; -} - -int32 -Private_Write(NPP instance, NPStream* stream, int32 offset, int32 len, - void* buffer) -{ - unsigned int result; - PLUGINDEBUGSTR("Write"); - result = NPP_Write(instance, stream, offset, len, buffer); - return result; -} - -void -Private_StreamAsFile(NPP instance, NPStream* stream, const char* fname) -{ - PLUGINDEBUGSTR("StreamAsFile"); - NPP_StreamAsFile(instance, stream, fname); -} - - -NPError -Private_DestroyStream(NPP instance, NPStream* stream, NPError reason) -{ - NPError err; - PLUGINDEBUGSTR("DestroyStream"); - err = NPP_DestroyStream(instance, stream, reason); - return err; -} - - -void -Private_Print(NPP instance, NPPrint* platformPrint) -{ - PLUGINDEBUGSTR("Print"); - NPP_Print(instance, platformPrint); -} - -JRIGlobalRef -Private_GetJavaClass(void) -{ - jref clazz = NPP_GetJavaClass(); - if (clazz) { - JRIEnv* env = NPN_GetJavaEnv(); - return JRI_NewGlobalRef(env, clazz); - } - return NULL; -} - -/*********************************************************************** - * - * These functions are located automagically by netscape. - * - ***********************************************************************/ - -/* - * NP_GetMIMEDescription - * - Netscape needs to know about this symbol - * - Netscape uses the return value to identify when an object instance - * of this plugin should be created. - */ -char * -NP_GetMIMEDescription(void) -{ - return NPP_GetMIMEDescription(); -} - -/* - * NP_GetValue [optional] - * - Netscape needs to know about this symbol. - * - Interfaces with plugin to get values for predefined variables - * that the navigator needs. - */ -NPError -NP_GetValue(void *future, NPPVariable variable, void *value) -{ - return NPP_GetValue(future, variable, value); -} - -/* - * NP_Initialize - * - Netscape needs to know about this symbol. - * - It calls this function after looking up its symbol before it - * is about to create the first ever object of this kind. - * - * PARAMETERS - * nsTable - The netscape function table. If developers just use these - * wrappers, they dont need to worry about all these function - * tables. - * RETURN - * pluginFuncs - * - This functions needs to fill the plugin function table - * pluginFuncs and return it. Netscape Navigator plugin - * library will use this function table to call the plugin. - * - */ -NPError -NP_Initialize(NPNetscapeFuncs* nsTable, NPPluginFuncs* pluginFuncs) -{ - NPError err = NPERR_NO_ERROR; - - PLUGINDEBUGSTR("NP_Initialize"); - - /* validate input parameters */ - - if ((nsTable == NULL) || (pluginFuncs == NULL)) - err = NPERR_INVALID_FUNCTABLE_ERROR; - - /* - * Check the major version passed in Netscape's function table. - * We won't load if the major version is newer than what we expect. - * Also check that the function tables passed in are big enough for - * all the functions we need (they could be bigger, if Netscape added - * new APIs, but that's OK with us -- we'll just ignore them). - * - */ - - if (err == NPERR_NO_ERROR) { - if ((nsTable->version >> 8) > NP_VERSION_MAJOR) - err = NPERR_INCOMPATIBLE_VERSION_ERROR; - if (nsTable->size < sizeof(NPNetscapeFuncs)) - err = NPERR_INVALID_FUNCTABLE_ERROR; - if (pluginFuncs->size < sizeof(NPPluginFuncs)) - err = NPERR_INVALID_FUNCTABLE_ERROR; - } - - - if (err == NPERR_NO_ERROR) { - /* - * Copy all the fields of Netscape function table into our - * copy so we can call back into Netscape later. Note that - * we need to copy the fields one by one, rather than assigning - * the whole structure, because the Netscape function table - * could actually be bigger than what we expect. - */ - gNetscapeFuncs.version = nsTable->version; - gNetscapeFuncs.size = nsTable->size; - gNetscapeFuncs.posturl = nsTable->posturl; - gNetscapeFuncs.geturl = nsTable->geturl; - gNetscapeFuncs.requestread = nsTable->requestread; - gNetscapeFuncs.newstream = nsTable->newstream; - gNetscapeFuncs.write = nsTable->write; - gNetscapeFuncs.destroystream = nsTable->destroystream; - gNetscapeFuncs.status = nsTable->status; - gNetscapeFuncs.uagent = nsTable->uagent; - gNetscapeFuncs.memalloc = nsTable->memalloc; - gNetscapeFuncs.memfree = nsTable->memfree; - gNetscapeFuncs.memflush = nsTable->memflush; - gNetscapeFuncs.reloadplugins = nsTable->reloadplugins; - gNetscapeFuncs.getJavaEnv = nsTable->getJavaEnv; - gNetscapeFuncs.getJavaPeer = nsTable->getJavaPeer; - gNetscapeFuncs.getvalue = nsTable->getvalue; - - /* - * Set up the plugin function table that Netscape will use to - * call us. Netscape needs to know about our version and size - * and have a UniversalProcPointer for every function we - * implement. - */ - pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; - pluginFuncs->size = sizeof(NPPluginFuncs); - pluginFuncs->newp = NewNPP_NewProc(Private_New); - pluginFuncs->destroy = NewNPP_DestroyProc(Private_Destroy); - pluginFuncs->setwindow = NewNPP_SetWindowProc(Private_SetWindow); - pluginFuncs->newstream = NewNPP_NewStreamProc(Private_NewStream); - pluginFuncs->destroystream = NewNPP_DestroyStreamProc(Private_DestroyStream); - pluginFuncs->asfile = NewNPP_StreamAsFileProc(Private_StreamAsFile); - pluginFuncs->writeready = NewNPP_WriteReadyProc(Private_WriteReady); - pluginFuncs->write = NewNPP_WriteProc(Private_Write); - pluginFuncs->print = NewNPP_PrintProc(Private_Print); - pluginFuncs->event = NULL; - pluginFuncs->javaClass = Private_GetJavaClass(); - - err = NPP_Initialize(); - } - - return err; -} - -/* - * NP_Shutdown [optional] - * - Netscape needs to know about this symbol. - * - It calls this function after looking up its symbol after - * the last object of this kind has been destroyed. - * - */ -NPError -NP_Shutdown(void) -{ - PLUGINDEBUGSTR("NP_Shutdown"); - NPP_Shutdown(); - return NPERR_NO_ERROR; -} diff --git a/src/signer/npinclude/npupp.h b/src/signer/npinclude/npupp.h deleted file mode 100644 index 44b18755..00000000 --- a/src/signer/npinclude/npupp.h +++ /dev/null @@ -1,995 +0,0 @@ -/* -*- Mode: C; tab-width: 4; -*- */ -/* - * npupp.h $Revision$ - * function call mecahnics needed by platform specific glue code. - */ - - -#ifndef _NPUPP_H_ -#define _NPUPP_H_ - -#ifndef GENERATINGCFM -#define GENERATINGCFM 0 -#endif - -#ifndef _NPAPI_H_ -#include "npapi.h" -#endif - -#include "jri.h" - -/****************************************************************************************** - plug-in function table macros - for each function in and out of the plugin API we define - typedef NPP_FooUPP - #define NewNPP_FooProc - #define CallNPP_FooProc - for mac, define the UPP magic for PPC/68K calling - *******************************************************************************************/ - - -/* NPP_Initialize */ - -#if GENERATINGCFM -typedef UniversalProcPtr NPP_InitializeUPP; - -enum { - uppNPP_InitializeProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0)) - | RESULT_SIZE(SIZE_CODE(0)) -}; - -#define NewNPP_InitializeProc(FUNC) \ - (NPP_InitializeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_InitializeProcInfo, GetCurrentArchitecture()) -#define CallNPP_InitializeProc(FUNC) \ - (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_InitializeProcInfo) - -#else - -typedef void (*NPP_InitializeUPP)(void); -#define NewNPP_InitializeProc(FUNC) \ - ((NPP_InitializeUPP) (FUNC)) -#define CallNPP_InitializeProc(FUNC) \ - (*(FUNC))() - -#endif - - -/* NPP_Shutdown */ - -#if GENERATINGCFM -typedef UniversalProcPtr NPP_ShutdownUPP; - -enum { - uppNPP_ShutdownProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(0)) - | RESULT_SIZE(SIZE_CODE(0)) -}; - -#define NewNPP_ShutdownProc(FUNC) \ - (NPP_ShutdownUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_ShutdownProcInfo, GetCurrentArchitecture()) -#define CallNPP_ShutdownProc(FUNC) \ - (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_ShutdownProcInfo) - -#else - -typedef void (*NPP_ShutdownUPP)(void); -#define NewNPP_ShutdownProc(FUNC) \ - ((NPP_ShutdownUPP) (FUNC)) -#define CallNPP_ShutdownProc(FUNC) \ - (*(FUNC))() - -#endif - - -/* NPP_New */ - -#if GENERATINGCFM -typedef UniversalProcPtr NPP_NewUPP; - -enum { - uppNPP_NewProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPMIMEType))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(uint16))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int16))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(char **))) - | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(char **))) - | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(NPSavedData *))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; - -#define NewNPP_NewProc(FUNC) \ - (NPP_NewUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_NewProcInfo, GetCurrentArchitecture()) -#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_NewProcInfo, \ - (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) -#else - -typedef NPError (*NPP_NewUPP)(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved); -#define NewNPP_NewProc(FUNC) \ - ((NPP_NewUPP) (FUNC)) -#define CallNPP_NewProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ - (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) - -#endif - - -/* NPP_Destroy */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_DestroyUPP; -enum { - uppNPP_DestroyProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPSavedData **))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPP_DestroyProc(FUNC) \ - (NPP_DestroyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_DestroyProcInfo, GetCurrentArchitecture()) -#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_DestroyProcInfo, (ARG1), (ARG2)) -#else - -typedef NPError (*NPP_DestroyUPP)(NPP instance, NPSavedData** save); -#define NewNPP_DestroyProc(FUNC) \ - ((NPP_DestroyUPP) (FUNC)) -#define CallNPP_DestroyProc(FUNC, ARG1, ARG2) \ - (*(FUNC))((ARG1), (ARG2)) - -#endif - - -/* NPP_SetWindow */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_SetWindowUPP; -enum { - uppNPP_SetWindowProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPWindow *))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPP_SetWindowProc(FUNC) \ - (NPP_SetWindowUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_SetWindowProcInfo, GetCurrentArchitecture()) -#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_SetWindowProcInfo, (ARG1), (ARG2)) - -#else - -typedef NPError (*NPP_SetWindowUPP)(NPP instance, NPWindow* window); -#define NewNPP_SetWindowProc(FUNC) \ - ((NPP_SetWindowUPP) (FUNC)) -#define CallNPP_SetWindowProc(FUNC, ARG1, ARG2) \ - (*(FUNC))((ARG1), (ARG2)) - -#endif - - -/* NPP_NewStream */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_NewStreamUPP; -enum { - uppNPP_NewStreamProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPMIMEType))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPStream *))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPBool))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(uint16 *))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPP_NewStreamProc(FUNC) \ - (NPP_NewStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_NewStreamProcInfo, GetCurrentArchitecture()) -#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_NewStreamProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) -#else - -typedef NPError (*NPP_NewStreamUPP)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype); -#define NewNPP_NewStreamProc(FUNC) \ - ((NPP_NewStreamUPP) (FUNC)) -#define CallNPP_NewStreamProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5) \ - (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5)) -#endif - - -/* NPP_DestroyStream */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_DestroyStreamUPP; -enum { - uppNPP_DestroyStreamProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPP_DestroyStreamProc(FUNC) \ - (NPP_DestroyStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_DestroyStreamProcInfo, GetCurrentArchitecture()) -#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_DestroyStreamProcInfo, (NPParg), (NPStreamPtr), (NPReasonArg)) - -#else - -typedef NPError (*NPP_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); -#define NewNPP_DestroyStreamProc(FUNC) \ - ((NPP_DestroyStreamUPP) (FUNC)) -#define CallNPP_DestroyStreamProc(FUNC, NPParg, NPStreamPtr, NPReasonArg) \ - (*(FUNC))((NPParg), (NPStreamPtr), (NPReasonArg)) - -#endif - - -/* NPP_WriteReady */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_WriteReadyUPP; -enum { - uppNPP_WriteReadyProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) - | RESULT_SIZE(SIZE_CODE(sizeof(int32))) -}; -#define NewNPP_WriteReadyProc(FUNC) \ - (NPP_WriteReadyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_WriteReadyProcInfo, GetCurrentArchitecture()) -#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \ - (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_WriteReadyProcInfo, (NPParg), (NPStreamPtr)) - -#else - -typedef int32 (*NPP_WriteReadyUPP)(NPP instance, NPStream* stream); -#define NewNPP_WriteReadyProc(FUNC) \ - ((NPP_WriteReadyUPP) (FUNC)) -#define CallNPP_WriteReadyProc(FUNC, NPParg, NPStreamPtr) \ - (*(FUNC))((NPParg), (NPStreamPtr)) - -#endif - - -/* NPP_Write */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_WriteUPP; -enum { - uppNPP_WriteProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int32))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(int32))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(void*))) - | RESULT_SIZE(SIZE_CODE(sizeof(int32))) -}; -#define NewNPP_WriteProc(FUNC) \ - (NPP_WriteUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_WriteProcInfo, GetCurrentArchitecture()) -#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \ - (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_WriteProcInfo, (NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr)) - -#else - -typedef int32 (*NPP_WriteUPP)(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer); -#define NewNPP_WriteProc(FUNC) \ - ((NPP_WriteUPP) (FUNC)) -#define CallNPP_WriteProc(FUNC, NPParg, NPStreamPtr, offsetArg, lenArg, bufferPtr) \ - (*(FUNC))((NPParg), (NPStreamPtr), (offsetArg), (lenArg), (bufferPtr)) - -#endif - - -/* NPP_StreamAsFile */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_StreamAsFileUPP; -enum { - uppNPP_StreamAsFileProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char *))) - | RESULT_SIZE(SIZE_CODE(0)) -}; -#define NewNPP_StreamAsFileProc(FUNC) \ - (NPP_StreamAsFileUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_StreamAsFileProcInfo, GetCurrentArchitecture()) -#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \ - (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_StreamAsFileProcInfo, (ARG1), (ARG2), (ARG3)) - -#else - -typedef void (*NPP_StreamAsFileUPP)(NPP instance, NPStream* stream, const char* fname); -#define NewNPP_StreamAsFileProc(FUNC) \ - ((NPP_StreamAsFileUPP) (FUNC)) -#define CallNPP_StreamAsFileProc(FUNC, ARG1, ARG2, ARG3) \ - (*(FUNC))((ARG1), (ARG2), (ARG3)) -#endif - - -/* NPP_Print */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_PrintUPP; -enum { - uppNPP_PrintProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPrint *))) - | RESULT_SIZE(SIZE_CODE(0)) -}; -#define NewNPP_PrintProc(FUNC) \ - (NPP_PrintUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_PrintProcInfo, GetCurrentArchitecture()) -#define CallNPP_PrintProc(FUNC, NPParg, voidPtr) \ - (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_PrintProcInfo, (NPParg), (voidPtr)) - -#else - -typedef void (*NPP_PrintUPP)(NPP instance, NPPrint* platformPrint); -#define NewNPP_PrintProc(FUNC) \ - ((NPP_PrintUPP) (FUNC)) -#define CallNPP_PrintProc(FUNC, NPParg, NPPrintArg) \ - (*(FUNC))((NPParg), (NPPrintArg)) - -#endif - - -/* NPP_HandleEvent */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_HandleEventUPP; -enum { - uppNPP_HandleEventProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(void *))) - | RESULT_SIZE(SIZE_CODE(sizeof(int16))) -}; -#define NewNPP_HandleEventProc(FUNC) \ - (NPP_HandleEventUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_HandleEventProcInfo, GetCurrentArchitecture()) -#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \ - (int16)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_HandleEventProcInfo, (NPParg), (voidPtr)) - -#else - -typedef int16 (*NPP_HandleEventUPP)(NPP instance, void* event); -#define NewNPP_HandleEventProc(FUNC) \ - ((NPP_HandleEventUPP) (FUNC)) -#define CallNPP_HandleEventProc(FUNC, NPParg, voidPtr) \ - (*(FUNC))((NPParg), (voidPtr)) - -#endif - - -/* NPP_URLNotify */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_URLNotifyUPP; -enum { - uppNPP_URLNotifyProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) - | RESULT_SIZE(SIZE_CODE(SIZE_CODE(0))) -}; -#define NewNPP_URLNotifyProc(FUNC) \ - (NPP_URLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_URLNotifyProcInfo, GetCurrentArchitecture()) -#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ - (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPP_URLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4)) - -#else - -typedef void (*NPP_URLNotifyUPP)(NPP instance, const char* url, NPReason reason, void* notifyData); -#define NewNPP_URLNotifyProc(FUNC) \ - ((NPP_URLNotifyUPP) (FUNC)) -#define CallNPP_URLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ - (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) - -#endif - - - - -/* - * Netscape entry points - */ - -#ifdef XP_UNIX - -/* NPN_GetValue */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_GetValueUPP; -enum { - uppNPN_GetValueProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPNVariable))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(void *))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPN_GetValueProc(FUNC) \ - (NPN_GetValueUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetValueProcInfo, GetCurrentArchitecture()) -#define CallNPN_GetURNotifyLProc(FUNC, ARG1, ARG2, ARG3) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetValueProcInfo, (ARG1), (ARG2), (ARG3)) -#else - -typedef NPError (*NPN_GetValueUPP)(NPP instance, NPNVariable variable, void *ret_alue); -#define NewNPN_GetValueProc(FUNC) \ - ((NPN_GetValueUPP) (FUNC)) -#define CallNPN_GetValueProc(FUNC, ARG1, ARG2, ARG3) \ - (*(FUNC))((ARG1), (ARG2), (ARG3)) -#endif - -#endif /* XP_UNIX */ - - - -/* NPN_GetUrlNotify */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_GetURLNotifyUPP; -enum { - uppNPN_GetURLNotifyProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPN_GetURLNotifyProc(FUNC) \ - (NPN_GetURLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetURLNotifyProcInfo, GetCurrentArchitecture()) -#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetURLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4)) -#else - -typedef NPError (*NPN_GetURLNotifyUPP)(NPP instance, const char* url, const char* window, void* notifyData); -#define NewNPN_GetURLNotifyProc(FUNC) \ - ((NPN_GetURLNotifyUPP) (FUNC)) -#define CallNPN_GetURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4) \ - (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4)) -#endif - - -/* NPN_PostUrlNotify */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_PostURLNotifyUPP; -enum { - uppNPN_PostURLNotifyProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(NPBool))) - | STACK_ROUTINE_PARAMETER(7, SIZE_CODE(sizeof(void*))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPN_PostURLNotifyProc(FUNC) \ - (NPN_PostURLNotifyUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PostURLNotifyProcInfo, GetCurrentArchitecture()) -#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PostURLNotifyProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) -#else - -typedef NPError (*NPN_PostURLNotifyUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData); -#define NewNPN_PostURLNotifyProc(FUNC) \ - ((NPN_PostURLNotifyUPP) (FUNC)) -#define CallNPN_PostURLNotifyProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7) \ - (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6), (ARG7)) -#endif - - -/* NPN_GetUrl */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_GetURLUPP; -enum { - uppNPN_GetURLProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPN_GetURLProc(FUNC) \ - (NPN_GetURLUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetURLProcInfo, GetCurrentArchitecture()) -#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetURLProcInfo, (ARG1), (ARG2), (ARG3)) -#else - -typedef NPError (*NPN_GetURLUPP)(NPP instance, const char* url, const char* window); -#define NewNPN_GetURLProc(FUNC) \ - ((NPN_GetURLUPP) (FUNC)) -#define CallNPN_GetURLProc(FUNC, ARG1, ARG2, ARG3) \ - (*(FUNC))((ARG1), (ARG2), (ARG3)) -#endif - - -/* NPN_PostUrl */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_PostURLUPP; -enum { - uppNPN_PostURLProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(uint32))) - | STACK_ROUTINE_PARAMETER(5, SIZE_CODE(sizeof(const char*))) - | STACK_ROUTINE_PARAMETER(6, SIZE_CODE(sizeof(NPBool))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPN_PostURLProc(FUNC) \ - (NPN_PostURLUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_PostURLProcInfo, GetCurrentArchitecture()) -#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_PostURLProcInfo, (ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) -#else - -typedef NPError (*NPN_PostURLUPP)(NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file); -#define NewNPN_PostURLProc(FUNC) \ - ((NPN_PostURLUPP) (FUNC)) -#define CallNPN_PostURLProc(FUNC, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6) \ - (*(FUNC))((ARG1), (ARG2), (ARG3), (ARG4), (ARG5), (ARG6)) -#endif - - -/* NPN_RequestRead */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_RequestReadUPP; -enum { - uppNPN_RequestReadProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPStream *))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPByteRange *))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPN_RequestReadProc(FUNC) \ - (NPN_RequestReadUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_RequestReadProcInfo, GetCurrentArchitecture()) -#define CallNPN_RequestReadProc(FUNC, stream, range) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_RequestReadProcInfo, (stream), (range)) - -#else - -typedef NPError (*NPN_RequestReadUPP)(NPStream* stream, NPByteRange* rangeList); -#define NewNPN_RequestReadProc(FUNC) \ - ((NPN_RequestReadUPP) (FUNC)) -#define CallNPN_RequestReadProc(FUNC, stream, range) \ - (*(FUNC))((stream), (range)) - -#endif - - -/* NPN_NewStream */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_NewStreamUPP; -enum { - uppNPN_NewStreamProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPMIMEType))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(const char *))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(NPStream **))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPN_NewStreamProc(FUNC) \ - (NPN_NewStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_NewStreamProcInfo, GetCurrentArchitecture()) -#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_NewStreamProcInfo, (npp), (type), (window), (stream)) - -#else - -typedef NPError (*NPN_NewStreamUPP)(NPP instance, NPMIMEType type, const char* window, NPStream** stream); -#define NewNPN_NewStreamProc(FUNC) \ - ((NPN_NewStreamUPP) (FUNC)) -#define CallNPN_NewStreamProc(FUNC, npp, type, window, stream) \ - (*(FUNC))((npp), (type), (window), (stream)) - -#endif - - -/* NPN_Write */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_WriteUPP; -enum { - uppNPN_WriteProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(int32))) - | STACK_ROUTINE_PARAMETER(4, SIZE_CODE(sizeof(void*))) - | RESULT_SIZE(SIZE_CODE(sizeof(int32))) -}; -#define NewNPN_WriteProc(FUNC) \ - (NPN_WriteUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_WriteProcInfo, GetCurrentArchitecture()) -#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \ - (int32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_WriteProcInfo, (npp), (stream), (len), (buffer)) - -#else - -typedef int32 (*NPN_WriteUPP)(NPP instance, NPStream* stream, int32 len, void* buffer); -#define NewNPN_WriteProc(FUNC) \ - ((NPN_WriteUPP) (FUNC)) -#define CallNPN_WriteProc(FUNC, npp, stream, len, buffer) \ - (*(FUNC))((npp), (stream), (len), (buffer)) - -#endif - - -/* NPN_DestroyStream */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_DestroyStreamUPP; -enum { - uppNPN_DestroyStreamProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP ))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPStream *))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPReason))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPN_DestroyStreamProc(FUNC) \ - (NPN_DestroyStreamUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_DestroyStreamProcInfo, GetCurrentArchitecture()) -#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \ - (NPError)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_DestroyStreamProcInfo, (npp), (stream), (reason)) - -#else - -typedef NPError (*NPN_DestroyStreamUPP)(NPP instance, NPStream* stream, NPReason reason); -#define NewNPN_DestroyStreamProc(FUNC) \ - ((NPN_DestroyStreamUPP) (FUNC)) -#define CallNPN_DestroyStreamProc(FUNC, npp, stream, reason) \ - (*(FUNC))((npp), (stream), (reason)) - -#endif - - -/* NPN_Status */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_StatusUPP; -enum { - uppNPN_StatusProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(char *))) -}; - -#define NewNPN_StatusProc(FUNC) \ - (NPN_StatusUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_StatusProcInfo, GetCurrentArchitecture()) -#define CallNPN_StatusProc(FUNC, npp, msg) \ - (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_StatusProcInfo, (npp), (msg)) - -#else - -typedef void (*NPN_StatusUPP)(NPP instance, const char* message); -#define NewNPN_StatusProc(FUNC) \ - ((NPN_StatusUPP) (FUNC)) -#define CallNPN_StatusProc(FUNC, npp, msg) \ - (*(FUNC))((npp), (msg)) - -#endif - - -/* NPN_UserAgent */ -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_UserAgentUPP; -enum { - uppNPN_UserAgentProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | RESULT_SIZE(SIZE_CODE(sizeof(const char *))) -}; - -#define NewNPN_UserAgentProc(FUNC) \ - (NPN_UserAgentUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_UserAgentProcInfo, GetCurrentArchitecture()) -#define CallNPN_UserAgentProc(FUNC, ARG1) \ - (const char*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_UserAgentProcInfo, (ARG1)) - -#else - -typedef const char* (*NPN_UserAgentUPP)(NPP instance); -#define NewNPN_UserAgentProc(FUNC) \ - ((NPN_UserAgentUPP) (FUNC)) -#define CallNPN_UserAgentProc(FUNC, ARG1) \ - (*(FUNC))((ARG1)) - -#endif - - -/* NPN_MemAlloc */ -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_MemAllocUPP; -enum { - uppNPN_MemAllocProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(uint32))) - | RESULT_SIZE(SIZE_CODE(sizeof(void *))) -}; - -#define NewNPN_MemAllocProc(FUNC) \ - (NPN_MemAllocUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemAllocProcInfo, GetCurrentArchitecture()) -#define CallNPN_MemAllocProc(FUNC, ARG1) \ - (void*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemAllocProcInfo, (ARG1)) - -#else - -typedef void* (*NPN_MemAllocUPP)(uint32 size); -#define NewNPN_MemAllocProc(FUNC) \ - ((NPN_MemAllocUPP) (FUNC)) -#define CallNPN_MemAllocProc(FUNC, ARG1) \ - (*(FUNC))((ARG1)) - -#endif - - -/* NPN__MemFree */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_MemFreeUPP; -enum { - uppNPN_MemFreeProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(void *))) -}; - -#define NewNPN_MemFreeProc(FUNC) \ - (NPN_MemFreeUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemFreeProcInfo, GetCurrentArchitecture()) -#define CallNPN_MemFreeProc(FUNC, ARG1) \ - (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemFreeProcInfo, (ARG1)) - -#else - -typedef void (*NPN_MemFreeUPP)(void* ptr); -#define NewNPN_MemFreeProc(FUNC) \ - ((NPN_MemFreeUPP) (FUNC)) -#define CallNPN_MemFreeProc(FUNC, ARG1) \ - (*(FUNC))((ARG1)) - -#endif - - -/* NPN_MemFlush */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_MemFlushUPP; -enum { - uppNPN_MemFlushProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(uint32))) - | RESULT_SIZE(SIZE_CODE(sizeof(uint32))) -}; - -#define NewNPN_MemFlushProc(FUNC) \ - (NPN_MemFlushUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_MemFlushProcInfo, GetCurrentArchitecture()) -#define CallNPN_MemFlushProc(FUNC, ARG1) \ - (uint32)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_MemFlushProcInfo, (ARG1)) - -#else - -typedef uint32 (*NPN_MemFlushUPP)(uint32 size); -#define NewNPN_MemFlushProc(FUNC) \ - ((NPN_MemFlushUPP) (FUNC)) -#define CallNPN_MemFlushProc(FUNC, ARG1) \ - (*(FUNC))((ARG1)) - -#endif - - - -/* NPN_ReloadPlugins */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_ReloadPluginsUPP; -enum { - uppNPN_ReloadPluginsProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPBool))) - | RESULT_SIZE(SIZE_CODE(0)) -}; - -#define NewNPN_ReloadPluginsProc(FUNC) \ - (NPN_ReloadPluginsUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_ReloadPluginsProcInfo, GetCurrentArchitecture()) -#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \ - (void)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_ReloadPluginsProcInfo, (ARG1)) - -#else - -typedef void (*NPN_ReloadPluginsUPP)(NPBool reloadPages); -#define NewNPN_ReloadPluginsProc(FUNC) \ - ((NPN_ReloadPluginsUPP) (FUNC)) -#define CallNPN_ReloadPluginsProc(FUNC, ARG1) \ - (*(FUNC))((ARG1)) - -#endif - - -/* NPN_GetJavaEnv */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_GetJavaEnvUPP; -enum { - uppNPN_GetJavaEnvProcInfo = kThinkCStackBased - | RESULT_SIZE(SIZE_CODE(sizeof(JRIEnv*))) -}; - -#define NewNPN_GetJavaEnvProc(FUNC) \ - (NPN_GetJavaEnvUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetJavaEnvProcInfo, GetCurrentArchitecture()) -#define CallNPN_GetJavaEnvProc(FUNC) \ - (JRIEnv*)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetJavaEnvProcInfo) - -#else - -typedef JRIEnv* (*NPN_GetJavaEnvUPP)(void); -#define NewNPN_GetJavaEnvProc(FUNC) \ - ((NPN_GetJavaEnvUPP) (FUNC)) -#define CallNPN_GetJavaEnvProc(FUNC) \ - (*(FUNC))() - -#endif - - -/* NPN_GetJavaPeer */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPN_GetJavaPeerUPP; -enum { - uppNPN_GetJavaPeerProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPP))) - | RESULT_SIZE(SIZE_CODE(sizeof(jref))) -}; - -#define NewNPN_GetJavaPeerProc(FUNC) \ - (NPN_GetJavaPeerUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPN_GetJavaPeerProcInfo, GetCurrentArchitecture()) -#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \ - (jref)CallUniversalProc((UniversalProcPtr)(FUNC), uppNPN_GetJavaPeerProcInfo, (ARG1)) - -#else - -typedef jref (*NPN_GetJavaPeerUPP)(NPP instance); -#define NewNPN_GetJavaPeerProc(FUNC) \ - ((NPN_GetJavaPeerUPP) (FUNC)) -#define CallNPN_GetJavaPeerProc(FUNC, ARG1) \ - (*(FUNC))((ARG1)) - -#endif - - - - -/****************************************************************************************** - * The actual plugin function table definitions - *******************************************************************************************/ - -typedef struct _NPPluginFuncs { - uint16 size; - uint16 version; - NPP_NewUPP newp; - NPP_DestroyUPP destroy; - NPP_SetWindowUPP setwindow; - NPP_NewStreamUPP newstream; - NPP_DestroyStreamUPP destroystream; - NPP_StreamAsFileUPP asfile; - NPP_WriteReadyUPP writeready; - NPP_WriteUPP write; - NPP_PrintUPP print; - NPP_HandleEventUPP event; - NPP_URLNotifyUPP urlnotify; - JRIGlobalRef javaClass; -} NPPluginFuncs; - -typedef struct _NPNetscapeFuncs { - uint16 size; - uint16 version; - NPN_GetURLUPP geturl; - NPN_PostURLUPP posturl; - NPN_RequestReadUPP requestread; - NPN_NewStreamUPP newstream; - NPN_WriteUPP write; - NPN_DestroyStreamUPP destroystream; - NPN_StatusUPP status; - NPN_UserAgentUPP uagent; - NPN_MemAllocUPP memalloc; - NPN_MemFreeUPP memfree; - NPN_MemFlushUPP memflush; - NPN_ReloadPluginsUPP reloadplugins; - NPN_GetJavaEnvUPP getJavaEnv; - NPN_GetJavaPeerUPP getJavaPeer; - NPN_GetURLNotifyUPP geturlnotify; - NPN_PostURLNotifyUPP posturlnotify; -#ifdef XP_UNIX - NPN_GetValueUPP getvalue; -#endif /* XP_UNIX */ -} NPNetscapeFuncs; - - - -#ifdef XP_MAC -/****************************************************************************************** - * Mac platform-specific plugin glue stuff - *******************************************************************************************/ - -/* - * Main entry point of the plugin. - * This routine will be called when the plugin is loaded. The function - * tables are passed in and the plugin fills in the NPPluginFuncs table - * and NPPShutdownUPP for Netscape's use. - */ - -#if GENERATINGCFM - -typedef UniversalProcPtr NPP_MainEntryUPP; -enum { - uppNPP_MainEntryProcInfo = kThinkCStackBased - | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(NPNetscapeFuncs*))) - | STACK_ROUTINE_PARAMETER(2, SIZE_CODE(sizeof(NPPluginFuncs*))) - | STACK_ROUTINE_PARAMETER(3, SIZE_CODE(sizeof(NPP_ShutdownUPP*))) - | RESULT_SIZE(SIZE_CODE(sizeof(NPError))) -}; -#define NewNPP_MainEntryProc(FUNC) \ - (NPP_MainEntryUPP) NewRoutineDescriptor((ProcPtr)(FUNC), uppNPP_MainEntryProcInfo, GetCurrentArchitecture()) -#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \ - CallUniversalProc((UniversalProcPtr)(FUNC), (ProcInfoType)uppNPP_MainEntryProcInfo, (netscapeFunc), (pluginFunc), (shutdownUPP)) - -#else - -typedef NPError (*NPP_MainEntryUPP)(NPNetscapeFuncs*, NPPluginFuncs*, NPP_ShutdownUPP*); -#define NewNPP_MainEntryProc(FUNC) \ - ((NPP_MainEntryUPP) (FUNC)) -#define CallNPP_MainEntryProc(FUNC, netscapeFunc, pluginFunc, shutdownUPP) \ - (*(FUNC))((netscapeFunc), (pluginFunc), (shutdownUPP)) - -#endif -#endif /* MAC */ - - -#ifdef _WINDOWS - -#ifdef __cplusplus -extern "C" { -#endif - -/* plugin meta member functions */ - -NPError WINAPI NP_GetEntryPoints(NPPluginFuncs* pFuncs); - -NPError WINAPI NP_Initialize(NPNetscapeFuncs* pFuncs); - -NPError WINAPI NP_Shutdown(); - -#ifdef __cplusplus -} -#endif - -#endif /* _WINDOWS */ - -#ifdef XP_UNIX - -#ifdef __cplusplus -extern "C" { -#endif - -/* plugin meta member functions */ - -char* NP_GetMIMEDescription(void); -NPError NP_Initialize(NPNetscapeFuncs*, NPPluginFuncs*); -NPError NP_Shutdown(void); - -#ifdef __cplusplus -} -#endif - -#endif /* XP_UNIX */ - -#endif /* _NPUPP_H_ */ diff --git a/src/signer/opensc-crypto.c b/src/signer/opensc-crypto.c deleted file mode 100644 index 2eccb5b3..00000000 --- a/src/signer/opensc-crypto.c +++ /dev/null @@ -1,228 +0,0 @@ -#include "signer.h" -#include "opensc-crypto.h" - -#define DBG(x) { x; } - -extern int ask_and_verify_pin_code(struct sc_pkcs15_card *p15card, - struct sc_pkcs15_object *pin); - -static void sc_close(struct sc_priv_data *priv) -{ - if (priv->p15card) { - sc_pkcs15_unbind(priv->p15card); - priv->p15card = NULL; - } - if (priv->card) { - sc_disconnect_card(priv->card, 0); - priv->card = NULL; - } - if (priv->ctx) { - sc_release_context(priv->ctx); - priv->ctx = NULL; - } -} - -static int -sc_init(struct sc_priv_data *priv) -{ - int r; - - r = sc_establish_context(&priv->ctx, "opensc-signer"); - if (r) - goto err; - r = sc_connect_card(priv->ctx->reader[priv->reader_id], 0, &priv->card); - if (r) - goto err; - r = sc_pkcs15_bind(priv->card, &priv->p15card); - if (r) - goto err; - return 0; -err: - sc_close(priv); - return r; -} - -static int sc_private_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, - int padding) -{ - int r; - struct sc_priv_data *priv; - struct sc_pkcs15_object *key, *pin; - - if (padding != RSA_PKCS1_PADDING) - return -1; - priv = (struct sc_priv_data *) RSA_get_app_data(rsa); - if (priv == NULL) - return -1; - if (priv->p15card == NULL) { - sc_close(priv); - r = sc_init(priv); - if (r || priv->p15card == NULL) { - DBG(printf("smart card init failed: %s", sc_strerror(r))); - goto err; - } - } - r = sc_pkcs15_find_prkey_by_id_usage(priv->p15card, - &priv->cert_id, - SC_PKCS15_PRKEY_USAGE_DECRYPT, - &key); - if (r) { - DBG(printf("Unable to find private key from smart card: %s", sc_strerror(r))); - goto err; - } - r = sc_pkcs15_find_pin_by_auth_id(priv->p15card, &key->auth_id, &pin); - if (r) { - DBG(printf("Unable to find PIN object from smart card: %s", sc_strerror(r))); - goto err; - } - - r = sc_lock(priv->p15card->card); - if (r != SC_SUCCESS) - goto err; - - r = ask_and_verify_pin_code(priv->p15card, pin); - if (r) { - sc_unlock(priv->p15card->card); - goto err; - } - r = sc_pkcs15_decipher(priv->p15card, (const struct sc_pkcs15_object *) key->data, 0, from, flen, to, flen); - sc_unlock(priv->p15card->card); - if (r < 0) { - DBG(printf("sc_pkcs15_decipher() failed: %s", sc_strerror(r))); - goto err; - } - return r; -err: - sc_close(priv); - return -1; -} - -static int -sc_private_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding) -{ - DBG(printf("unsupported function sc_private_encrypt() called")); - return -1; -} - -static int -sc_sign(int type, const unsigned char *m, unsigned int m_len, - unsigned char *sigret, unsigned int *siglen, const RSA *rsa) -{ - int r; - struct sc_priv_data *priv; - struct sc_pkcs15_object *key, *pin; - - priv = (struct sc_priv_data *) RSA_get_app_data(rsa); - if (priv == NULL) - return -1; - DBG(printf("sc_sign() called on cert %02X: type = %d, m_len = %d", - priv->cert_id.value[0], type, m_len)); - if (priv->p15card == NULL) { - sc_close(priv); - r = sc_init(priv); - if (r || priv->p15card == NULL) { - DBG(printf("smart card init failed: %s", sc_strerror(r))); - goto err; - } - } - r = sc_pkcs15_find_prkey_by_id_usage(priv->p15card, - &priv->cert_id, - SC_PKCS15_PRKEY_USAGE_SIGN, - &key); - if (r) { - DBG(printf("Unable to find private key from smart card: %s", sc_strerror(r))); - goto err; - } - r = sc_pkcs15_find_pin_by_auth_id(priv->p15card, &key->auth_id, &pin); - if (r) { - DBG(printf("Unable to find PIN object from smart card: %s", sc_strerror(r))); - goto err; - } - - r = sc_lock(priv->p15card->card); - if (r != SC_SUCCESS) - goto err; - - r = ask_and_verify_pin_code(priv->p15card, pin); - if (r) { - sc_unlock(priv->p15card->card); - goto err; - } - DBG(printf("PIN code received successfully.\n")); - r = sc_pkcs15_compute_signature(priv->p15card, key, - SC_ALGORITHM_RSA_HASH_SHA1 | SC_ALGORITHM_RSA_PAD_PKCS1, - m, m_len, sigret, RSA_size(rsa)); - sc_unlock(priv->p15card->card); - if (r < 0) { - DBG(printf("sc_pkcs15_compute_signature() failed: %s", sc_strerror(r))); - goto err; - } - *siglen = r; - DBG(printf("Received signature from card (%d bytes).\n", r)); - return 1; -err: - printf("Returning with error %s\n", sc_strerror(r)); - sc_close(priv); - return 0; -} - -static int (*orig_finish)(RSA *rsa) = NULL; - -static int -sc_finish(RSA *rsa) -{ - struct sc_priv_data *priv; - - DBG(printf("sc_finish() called\n")); - priv = (struct sc_priv_data *) RSA_get_app_data(rsa); - if (priv != NULL) { - priv->ref_count--; - if (priv->ref_count == 0) { - sc_close(priv); - free(priv); - } - } - if (orig_finish) - orig_finish(rsa); - return 1; -} - -static RSA_METHOD opensc_rsa = -{ - "OpenSC", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - 0, - NULL, -}; - -RSA_METHOD * sc_get_method(void) -{ - const RSA_METHOD *def; - - def = RSA_get_default_method(); - orig_finish = def->finish; - - /* overload */ - opensc_rsa.rsa_priv_enc = sc_private_encrypt; - opensc_rsa.rsa_priv_dec = sc_private_decrypt; - opensc_rsa.rsa_sign = sc_sign; - opensc_rsa.finish = sc_finish; - - /* just use the OpenSSL version */ - opensc_rsa.rsa_pub_enc = def->rsa_pub_enc; - opensc_rsa.rsa_pub_dec = def->rsa_pub_dec; - opensc_rsa.rsa_mod_exp = def->rsa_mod_exp; - opensc_rsa.bn_mod_exp = def->bn_mod_exp; - opensc_rsa.init = def->init; - opensc_rsa.flags = def->flags | RSA_FLAG_SIGN_VER; - opensc_rsa.app_data = def->app_data; - opensc_rsa.rsa_verify = def->rsa_verify; - return &opensc_rsa; -} diff --git a/src/signer/opensc-crypto.h b/src/signer/opensc-crypto.h deleted file mode 100644 index c4da5d0c..00000000 --- a/src/signer/opensc-crypto.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _OPENSC_CRYPTO_H -#define _OPENSC_CRYPTO_H - -#include -#include - -struct sc_priv_data -{ - struct sc_pkcs15_card *p15card; - struct sc_card *card; - struct sc_context *ctx; - struct sc_pkcs15_id cert_id; - int ref_count, reader_id; -}; - -extern RSA_METHOD * sc_get_method(void); - -#endif diff --git a/src/signer/opensc-support.c b/src/signer/opensc-support.c deleted file mode 100644 index 76f31d35..00000000 --- a/src/signer/opensc-support.c +++ /dev/null @@ -1,242 +0,0 @@ -#include "opensc-support.h" -#include "opensc-crypto.h" -#include -#include -#include - -static int get_certificate(PluginInstance *inst, - X509 **cert_out, struct sc_pkcs15_id *certid_out) -{ - struct sc_pkcs15_cert *cert; - struct sc_pkcs15_cert_info *cinfo; - struct sc_pkcs15_object *objs[32], *cert_obj; - int r, i, count; - X509 *x509; - struct sc_pkcs15_id cert_id; - const u8 *p; - - r = sc_pkcs15_get_objects(inst->p15card, SC_PKCS15_TYPE_PRKEY_RSA, objs, 32); - if (r < 0) - return r; - if (r == 0) - return SC_ERROR_OBJECT_NOT_FOUND; - cert_id.len = 0; - count = r; - for (i = 0; i < count; i++) { - struct sc_pkcs15_prkey_info *key = (struct sc_pkcs15_prkey_info *) objs[i]->data; - -#if 0 - if (key->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) { -#endif - /* Use the first available non-repudiation key */ - cert_id = key->id; - break; -#if 0 - } -#endif - } - if (cert_id.len == 0) - return SC_ERROR_OBJECT_NOT_FOUND; - r = sc_pkcs15_find_cert_by_id(inst->p15card, &cert_id, &cert_obj); - if (r) - return r; - cinfo = (struct sc_pkcs15_cert_info *) cert_obj->data; - r = sc_pkcs15_read_certificate(inst->p15card, cinfo, &cert); - if (r) - return r; - x509 = X509_new(); - p = cert->data; - if (!d2i_X509(&x509, &p, cert->data_len)) { - return -1; /* FIXME */ - } - *certid_out = cinfo->id; - sc_pkcs15_free_certificate(cert); - *cert_out = x509; - return 0; -} - -static int init_pkcs15(PluginInstance *inst) -{ - int r; - - r = sc_establish_context(&inst->ctx, "opensc-signer"); - if (r) - return r; - inst->reader_id = 0; - r = sc_connect_card(inst->ctx->reader[inst->reader_id], 0, &inst->card); - if (r) - return r; - r = sc_pkcs15_bind(inst->card, &inst->p15card); - if (r) - return r; - return 0; -} - -#if 0 -static void close_pkcs15(PluginInstance *inst) -{ - if (inst->p15card) { - sc_pkcs15_unbind(inst->p15card); - inst->p15card = NULL; - } - if (inst->card) { - sc_disconnect_card(inst->card, 0); - inst->card = NULL; - } - if (inst->ctx) { - sc_release_context(inst->ctx); - inst->ctx = NULL; - } -} -#endif - -static int extract_certificate_and_pkey(PluginInstance *inst, - X509 **x509_out, - EVP_PKEY **pkey_out) -{ - int r; - X509 *x509 = NULL; - struct sc_pkcs15_id cert_id; - struct sc_priv_data *priv = NULL; - EVP_PKEY *pkey = NULL; - RSA *rsa = NULL; - - r = init_pkcs15(inst); - if (r) - goto err; - r = get_certificate(inst, &x509, &cert_id); - if (r) - goto err; - - r = -1; - pkey = X509_get_pubkey(x509); - if (pkey == NULL) - goto err; - if (pkey->type != EVP_PKEY_RSA) - goto err; - rsa = EVP_PKEY_get1_RSA(pkey); /* increases ref count */ - if (rsa == NULL) - goto err; - rsa->flags |= RSA_FLAG_SIGN_VER; - RSA_set_method(rsa, sc_get_method()); - priv = (struct sc_priv_data *) calloc(1, sizeof(*priv)); - if (priv == NULL) - goto err; - priv->cert_id = cert_id; - priv->ref_count = 1; - RSA_set_app_data(rsa, priv); - RSA_free(rsa); /* decreases ref count */ - - *x509_out = x509; - *pkey_out = pkey; - - return 0; -err: - if (pkey) - EVP_PKEY_free(pkey); - if (x509) - X509_free(x509); - return -1; - -} - -int create_envelope(PluginInstance *inst, u8 **data, int *datalen) -{ - int r; - PKCS7 *p7 = NULL; - X509 *x509 = NULL; - PKCS7_SIGNER_INFO *si = NULL; - EVP_PKEY *pkey = NULL; - BIO *in = NULL, *p7bio = NULL; - u8 *buf; - - r = extract_certificate_and_pkey(inst, &x509, &pkey); - if (r) - goto err; - p7 = PKCS7_new(); - if (p7 == NULL) { - r = -1; - goto err; - } - r = PKCS7_set_type(p7, NID_pkcs7_signed); - if (r != 1) { - r = -1; - goto err; - } - EVP_add_digest(EVP_sha1()); - si = PKCS7_add_signature(p7, x509, pkey, EVP_sha1()); - if (si == NULL) { - r = -1; - goto err; - } - PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, - OBJ_nid2obj(NID_pkcs7_data)); - r = PKCS7_add_certificate(p7, x509); - if (r != 1) { - printf("PKCS7_add_certificate failed.\n"); - goto err; - } - PKCS7_content_new(p7, NID_pkcs7_data); - - p7bio = PKCS7_dataInit(p7, NULL); - if (p7bio == NULL) { - r = -1; - goto err; - } - in = BIO_new_mem_buf(inst->signdata, inst->signdata_len); - if (in == NULL) { - r = -1; - goto err; - } - for (;;) { - char lbuf[1024]; - int i = BIO_read(in, lbuf, sizeof(lbuf)); - if (i <= 0) - break; - BIO_write(p7bio, lbuf, i); - } - if (!PKCS7_dataFinal(p7, p7bio)) { - r = -1; - goto err; - } - /* FIXME: remove this */ - r = i2d_PKCS7(p7, NULL); - if (r <= 0) { - r = -1; - goto err; - } - buf = (u8 *) malloc(r); - if (buf == NULL) - goto err; - *data = buf; - r = i2d_PKCS7(p7, &buf); - *datalen = r; - if (r <= 0) { - free(buf); - r = -1; - goto err; - } - r = 0; -err: - if (p7) - PKCS7_free(p7); - if (in) - BIO_free(in); - if (p7bio) - BIO_free(p7bio); -#if 0 - if (si) - PKCS7_SIGNER_INFO_free(si); -#endif - if (pkey) - EVP_PKEY_free(pkey); - if (x509) - X509_free(x509); - if (r) { -#if 0 - ERR_load_crypto_strings(); - ERR_print_errors_fp(stderr); -#endif - } - return r; -} diff --git a/src/signer/opensc-support.h b/src/signer/opensc-support.h deleted file mode 100644 index 4c66bbb1..00000000 --- a/src/signer/opensc-support.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _OPENSC_SUPPORT_H -#define _OPENSC_SUPPORT_H - -#include "signer.h" - -extern int create_envelope(PluginInstance *inst, u8 **data, int *datalen); - -#endif diff --git a/src/signer/signer.c b/src/signer/signer.c deleted file mode 100644 index 5cac8476..00000000 --- a/src/signer/signer.c +++ /dev/null @@ -1,374 +0,0 @@ -#include -#include -#include "npinclude/npapi.h" -#include "signer.h" -#include "opensc-support.h" - -char* -NPP_GetMIMEDescription(void) -{ - return (char *) "text/x-text-to-sign:sgn:Text to be signed"; -} - -NPError -NPP_GetValue(void *inst, NPPVariable variable, void *value) -{ - NPError err = NPERR_NO_ERROR; - - printf("NPP_GetValue()\n"); - switch (variable) { - case NPPVpluginNameString: - *((char **)value) = (char *) "OpenSC Signer plugin"; - break; - case NPPVpluginDescriptionString: - *((char **)value) = (char *) "This plugins handles" - " web signatures using OpenSC" - " smart card library."; - break; - default: - err = NPERR_GENERIC_ERROR; - } - return err; -} - -NPError -NPP_Initialize(void) -{ - printf("NPP_Initialize()\n"); - return NPERR_NO_ERROR; -} - - -jref -NPP_GetJavaClass(void) -{ - printf("NPP_GetJavaClass()\n"); - return NULL; -} - -void -NPP_Shutdown(void) -{ - printf("NPP_Shutdown()\n"); -} - -static NPError -post_data(NPP instance, const char *url, const char *target, uint32 len, - const char *buf, const char *tag) -{ - NPError rv; - char headers[256], *sendbuf; - char *content; - unsigned int content_len, hdrlen, taglen; - - taglen = strlen(tag); - content_len = taglen + len + 1; - content = (char *) NPN_MemAlloc(content_len); - if (content == NULL) - return NPERR_OUT_OF_MEMORY_ERROR; - memcpy(content, tag, taglen); - content[taglen] = '='; - memcpy(content+taglen+1, buf, len); - - sprintf(headers, "Content-type: application/x-www-form-urlencoded\r\n" - "Content-Length: %u\r\n\r\n", (unsigned int) content_len); - hdrlen = strlen(headers); - sendbuf = (char *) NPN_MemAlloc(hdrlen + content_len); - if (sendbuf == NULL) - return NPERR_OUT_OF_MEMORY_ERROR; - memcpy(sendbuf, headers, hdrlen); - memcpy(sendbuf + hdrlen, content, content_len); - sendbuf[hdrlen + content_len] = 0; - NPN_MemFree(content); - printf("Sending:\n---\n%s---\n", sendbuf); - printf("Url: '%s', target: '%s', len: %ld\n", url, target, hdrlen + len); - rv = NPN_PostURL(instance, url, target, hdrlen + content_len, sendbuf, FALSE); - - return rv; -} - -NPError -NPP_New(NPMIMEType pluginType, - NPP instance, - uint16 mode, - int16 argc, - char* argn[], - char* argv[], - NPSavedData* saved) -{ - PluginInstance* This = NULL; - NPError rv; - int r, i, datalen, b64datalen; - u8 *data = NULL, *b64data = NULL; - char *postUrl = NULL, *dataToSign = NULL, *fieldName = NULL; - - printf("NPP_New()\n"); - if (instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - instance->pdata = NPN_MemAlloc(sizeof(PluginInstance)); - - This = (PluginInstance*) instance->pdata; - - if (This == NULL) - return NPERR_OUT_OF_MEMORY_ERROR; - - This->ctx = NULL; - This->card = NULL; - This->p15card = NULL; - - for (i = 0; i < argc; i++) { - if (strcmp(argn[i], "wsxaction") == 0) { - postUrl = strdup(argv[i]); - } else if (strcmp(argn[i], "wsxdatatosign") == 0) { - dataToSign = strdup(argv[i]); - } else if (strcmp(argn[i], "wsxname") == 0) { - fieldName = strdup(argv[i]); - } else - printf("'%s' = '%s'\n", argn[i], argv[i]); - } - if (postUrl == NULL || dataToSign == NULL) { - r = NPERR_GENERIC_ERROR; - goto err; - } - if (fieldName == NULL) - fieldName = strdup("SignedData"); - This->signdata = dataToSign; - This->signdata_len = strlen(dataToSign); - - r = create_envelope(This, &data, &datalen); - if (r) { - r = NPERR_GENERIC_ERROR; - goto err; - } - b64datalen = datalen * 4 / 3 + 4; - b64data = (u8 *) malloc(b64datalen); - r = sc_base64_encode(data, datalen, b64data, b64datalen, 0); - if (r) { - r = NPERR_GENERIC_ERROR; - goto err; - } - printf("Posting to '%s'\n", postUrl); - printf("Data to sign: %s\n", dataToSign); - printf("Signed: %s\n", b64data); - rv = post_data(instance, postUrl, "_self", strlen((char *) b64data), (char *) b64data, - fieldName); - printf("post_data returned %d\n", rv); - r = NPERR_NO_ERROR; -err: - if (fieldName) - free(fieldName); - if (dataToSign) - free(dataToSign); - if (postUrl) - free(postUrl); - if (data) - free(data); - if (b64data) - free(b64data); - return r; -} - -NPError -NPP_Destroy(NPP instance, NPSavedData** save) -{ - PluginInstance* This; - - printf("NPP_Destroy()\n"); - if (instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - This = (PluginInstance*) instance->pdata; - - /* PLUGIN DEVELOPERS: - * If desired, call NP_MemAlloc to create a - * NPSavedDate structure containing any state information - * that you want restored if this plugin instance is later - * recreated. - */ - if (This == NULL) - return NPERR_NO_ERROR; - - NPN_MemFree(instance->pdata); - instance->pdata = NULL; - - return NPERR_NO_ERROR; -} - - - -NPError -NPP_SetWindow(NPP instance, NPWindow* window) -{ - PluginInstance* This; - Display *dpy; - NPSetWindowCallbackStruct *ws; - Window win; - - printf("NPP_SetWindow()\n"); - - if (instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - if (window == NULL) - return NPERR_NO_ERROR; - - This = (PluginInstance*) instance->pdata; - ws = (NPSetWindowCallbackStruct *) window->ws_info; - dpy = ws->display; - win = (Window) window->window; - - /* - * PLUGIN DEVELOPERS: - * Before setting window to point to the - * new window, you may wish to compare the new window - * info to the previous window (if any) to note window - * size changes, etc. - */ - - - return NPERR_NO_ERROR; -} - - -NPError -NPP_NewStream(NPP instance, - NPMIMEType type, - NPStream *stream, - NPBool seekable, - uint16 *stype) -{ - PluginInstance* This; - printf("NPP_NewStream()\n"); - - if (instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - - This = (PluginInstance*) instance->pdata; - - return NPERR_NO_ERROR; -} - - -/* PLUGIN DEVELOPERS: - * These next 2 functions are directly relevant in a plug-in which - * handles the data in a streaming manner. If you want zero bytes - * because no buffer space is YET available, return 0. As long as - * the stream has not been written to the plugin, Navigator will - * continue trying to send bytes. If the plugin doesn't want them, - * just return some large number from NPP_WriteReady(), and - * ignore them in NPP_Write(). For a NP_ASFILE stream, they are - * still called but can safely be ignored using this strategy. - */ - -int32 STREAMBUFSIZE = 0X0FFFFFFF; /* If we are reading from a file in NPAsFile - * mode so we can take any size stream in our - * write call (since we ignore it) */ - -int32 -NPP_WriteReady(NPP instance, NPStream *stream) -{ - PluginInstance* This; - if (instance != NULL) - This = (PluginInstance*) instance->pdata; - printf("NPP_WriteReady()\n"); - return STREAMBUFSIZE; -} - - -int32 -NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, void *buffer) -{ -#if 0 - if (instance != NULL) - { - PluginInstance* This = (PluginInstance*) instance->pdata; - } -#endif - printf("NPP_Write(offset %d, len %d)\n", (int) offset, (int) len); - - return len; /* The number of bytes accepted */ -} - - -NPError -NPP_DestroyStream(NPP instance, NPStream *stream, NPError reason) -{ - PluginInstance* This; - - if (instance == NULL) - return NPERR_INVALID_INSTANCE_ERROR; - This = (PluginInstance*) instance->pdata; - printf("NPP_DestroyStream()\n"); - - return NPERR_NO_ERROR; -} - - -void -NPP_StreamAsFile(NPP instance, NPStream *stream, const char* fname) -{ - PluginInstance* This; - - if (instance != NULL) - This = (PluginInstance*) instance->pdata; - printf("NPP_StreamAsFile('%s')\n", fname); -} - - -void -NPP_Print(NPP instance, NPPrint* printInfo) -{ -#if 0 - if(printInfo == NULL) - return; - - if (instance != NULL) { - PluginInstance* This = (PluginInstance*) instance->pdata; - - if (printInfo->mode == NP_FULL) { - /* - * PLUGIN DEVELOPERS: - * If your plugin would like to take over - * printing completely when it is in full-screen mode, - * set printInfo->pluginPrinted to TRUE and print your - * plugin as you see fit. If your plugin wants Netscape - * to handle printing in this case, set - * printInfo->pluginPrinted to FALSE (the default) and - * do nothing. If you do want to handle printing - * yourself, printOne is true if the print button - * (as opposed to the print menu) was clicked. - * On the Macintosh, platformPrint is a THPrint; on - * Windows, platformPrint is a structure - * (defined in npapi.h) containing the printer name, port, - * etc. - */ - - void* platformPrint = - printInfo->print.fullPrint.platformPrint; - NPBool printOne = - printInfo->print.fullPrint.printOne; - - /* Do the default*/ - printInfo->print.fullPrint.pluginPrinted = FALSE; - } - else { /* If not fullscreen, we must be embedded */ - /* - * PLUGIN DEVELOPERS: - * If your plugin is embedded, or is full-screen - * but you returned false in pluginPrinted above, NPP_Print - * will be called with mode == NP_EMBED. The NPWindow - * in the printInfo gives the location and dimensions of - * the embedded plugin on the printed page. On the - * Macintosh, platformPrint is the printer port; on - * Windows, platformPrint is the handle to the printing - * device context. - */ - - NPWindow* printWindow = - &(printInfo->print.embedPrint.window); - void* platformPrint = - printInfo->print.embedPrint.platformPrint; - } - } -#endif -} diff --git a/src/signer/signer.exports b/src/signer/signer.exports deleted file mode 100644 index b3887e91..00000000 --- a/src/signer/signer.exports +++ /dev/null @@ -1,34 +0,0 @@ -NPP_Initialize -NPN_RequestRead -NPP_Destroy -NPN_ReloadPlugins -NPN_GetJavaEnv -NP_GetValue -NPN_Version -NPN_NewStream -NPN_MemFree -NPN_GetURL -NPN_Write -NP_GetMIMEDescription -NPN_PostURL -NPN_MemAlloc -NPP_SetWindow -NPN_MemFlush -NPP_Print -NPP_StreamAsFile -NPP_GetMIMEDescription -NP_Initialize -NPP_DestroyStream -NPP_GetValue -NP_Shutdown -NPP_Write -NPN_UserAgent -NPP_NewStream -NPP_New -NPN_GetJavaPeer -NPN_Status -NPP_GetJavaClass -NPN_DestroyStream -NPP_Shutdown -NPP_WriteReady -NPN_GetValue diff --git a/src/signer/signer.h b/src/signer/signer.h deleted file mode 100644 index 745b77c5..00000000 --- a/src/signer/signer.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef _SIGNER_H -#define _SIGNER_H - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include - -typedef struct _PluginInstance -{ - char *signdata; - int signdata_len; - int reader_id; - struct sc_context *ctx; - struct sc_card *card; - struct sc_pkcs15_card *p15card; - - const char *pinname; - char *pinbuf; - int pinlen; -} PluginInstance; - -#ifdef __cplusplus -extern "C" { -#endif - -int ask_pin_code(PluginInstance *inst); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/signer/stubs.c b/src/signer/stubs.c deleted file mode 100644 index 5ca60618..00000000 --- a/src/signer/stubs.c +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- Mode: C; tab-width: 4; -*- */ -/******************************************************************************* - * Simple LiveConnect Sample Plugin - * Copyright (c) 1996 Netscape Communications. All rights reserved. - ******************************************************************************/ - -/* -** Ok, so we don't usually include .c files (only .h files) but we're -** doing it here to avoid some fancy make rules. First pull in the common -** glue code: -*/ -#ifdef XP_UNIX -#include "npunix.c" -#endif diff --git a/src/signer/testprog.c b/src/signer/testprog.c deleted file mode 100644 index 74b8bc34..00000000 --- a/src/signer/testprog.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -#include -#include "opensc-support.h" -#include "opensc-crypto.h" -#include "signer.h" - -int test(void) -{ - BIO *in; - PKCS7 *p7; - - in = BIO_new_file("sample.pem", "r"); - p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); - if (p7 == NULL) { - goto err; - } -#if 0 - return prp7(p7); -#endif - return 0; -err: - ERR_load_crypto_strings(); - ERR_print_errors_fp(stderr); - return 1; -} - -int main(void) -{ - PluginInstance pl; - u8 *data; - int datalen, r; - -#if 0 - test(); - return 0; -#endif - - pl.signdata = strdup("12345\ntest foo bar one two three\nTesting 1234567890"); - pl.signdata_len = strlen(pl.signdata); - r = create_envelope(&pl, &data, &datalen); - if (r) { - printf("create_env() failed\n"); - return 1; - } - return 0; -} From 0eac0fb14cabb83bb901870d42102d2d800ba9a3 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 12:25:18 +0000 Subject: [PATCH 55/57] Fix #58: properly document "pkcs15-init -T" git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3841 c6295689-39f2-0310-b995-f0e70906c6a9 --- doc/tools/pkcs15-init.xml | 11 +++++++++++ src/tools/pkcs15-init.c | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/tools/pkcs15-init.xml b/doc/tools/pkcs15-init.xml index 9be31a7f..9e7a29a8 100644 --- a/doc/tools/pkcs15-init.xml +++ b/doc/tools/pkcs15-init.xml @@ -341,6 +341,17 @@ + + , + + + + Tells pkcs15-init to not ask for the transport + keys and use default keys, as known by the card driver. + + + + diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 6113cdbb..82f58ddc 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -227,7 +227,7 @@ static const char * option_help[] = { "Private key stored as an extractable key", "Insecure mode: do not require PIN/passphrase for private key", "Use software key generation, even if the card supports on-board key generation", - "Always ask for transport keys etc, even if the driver thinks it knows the key", + "Do not ask for transport keys if the driver thinks it knows the key", "Do not prompt the user, except for PINs", "Specify the general profile to use", From 533a33521f4295fc1b3b4d55f65863e452c8ab87 Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 14:51:32 +0000 Subject: [PATCH 56/57] * Update opensc-tool and opensc-explorer man pages * Remove not implemented pksign/pkdecrypt commands from opensc-explorer. Use pkcs15-crypt instead. git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3843 c6295689-39f2-0310-b995-f0e70906c6a9 --- doc/tools/opensc-explorer.xml | 16 +--- doc/tools/opensc-tool.xml | 13 +++ src/tools/opensc-explorer.c | 172 ---------------------------------- 3 files changed, 17 insertions(+), 184 deletions(-) diff --git a/doc/tools/opensc-explorer.xml b/doc/tools/opensc-explorer.xml index 608087b8..9680e593 100644 --- a/doc/tools/opensc-explorer.xml +++ b/doc/tools/opensc-explorer.xml @@ -58,6 +58,10 @@ auto-detected. + + + Wait for a card to be inserted + @@ -152,18 +156,6 @@ and size is the size of the new file. - - - create a public key signature. NOTE: This command is currently not implemented. - - - - - - perform a public key decryption. NOTE: This command is currently not implemented. - - - erase the card, if the card supports it. diff --git a/doc/tools/opensc-tool.xml b/doc/tools/opensc-tool.xml index 315a4554..8b6c26e0 100644 --- a/doc/tools/opensc-tool.xml +++ b/doc/tools/opensc-tool.xml @@ -31,11 +31,20 @@ Options + + + Print information about OpenSC, such as version and enabled components + + Print the Answer To Reset (ATR) of the card, output is in hex byte format + + + Print the name of the inserted card (driver) + Print the card serial number (normally the ICCSN), output is in hex byte @@ -70,6 +79,10 @@ in the system. driver, driver Use the given card driver. The default is auto-detected. + + + Wait for a card to be inserted + Causes opensc-tool to be more verbose. Specify this flag several times diff --git a/src/tools/opensc-explorer.c b/src/tools/opensc-explorer.c index 8d78e287..cbdf56c1 100644 --- a/src/tools/opensc-explorer.c +++ b/src/tools/opensc-explorer.c @@ -60,19 +60,6 @@ static const char *option_help[] = { "Verbose operation. Use several times to enable debug output.", }; - -#if 0 /* fixme: uncomment for use with pksign */ -static u8 oid_md5[18] = /* MD5 OID is 1.2.840.113549.2.5 */ -{ 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48, - 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 }; -static u8 oid_sha1[15] = /* SHA-1 OID 1.3.14.3.2.26 */ -{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; -static u8 oid_rmd160[15] = /* RIPE MD-160 OID is 1.3.36.3.2.1 */ -{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; -#endif - static size_t hex2binary(u8 *out, size_t outlen, const char *in); struct command { @@ -1176,163 +1163,6 @@ static int do_debug(int argc, char **argv) } -static int do_pksign(int argc, char **argv) -{ - puts ("Not yet supported"); - return -1; -#if 0 - int i, ref, r; - u8 indata[128]; - size_t indatalen = sizeof indata; - u8 outdata[128]; - size_t outdatalen = sizeof outdata; - sc_security_env_t senv; - const u8 *oid; - int oidlen; - const char *s; - - if (argc < 2 || argc > 3) - goto usage; - if (sscanf (argv[0], "%d", &ref) != 1 || ref < 0 || ref > 255) { - printf("Invalid key reference.\n"); - goto usage; - } - - if (argv[1][0] == '"') { - for (s = argv[1]+1, i = 0; - i < sizeof indata && *s && *s != '"'; i++) - indata[i] = *s++; - indatalen = i; - } else if (sc_hex_to_bin(argv[1], indata, &indatalen)) { - printf("Invalid data value.\n"); - goto usage; - } - - - if (argc == 3) { - if (!strcasecmp(argv[2], "SHA1")) { - oid = oid_sha1; oidlen = sizeof oid_sha1; - } - else if (!strcasecmp (argv[2], "MD5")) { - oid = oid_md5; oidlen = sizeof oid_md5; - } - else if (!strcasecmp (argv[2], "RMD160")) { - oid = oid_rmd160; oidlen = sizeof oid_rmd160; - } - else { - goto usage; - } - } - else { - oid = ""; oidlen = 0; - } - - if (indatalen + oidlen > sizeof indata) { - printf("Data value to long.\n"); - goto usage; - } - - memmove(indata + oidlen, indata, indatalen); - memcpy(indata, oid, oidlen); - indatalen += oidlen; - - /* setup the security environment */ - /* FIXME The values won't work for other cards. They do work - for TCOS because there is no need for a security - environment there */ - memset(&senv, 0, sizeof senv); - senv.operation = SC_SEC_OPERATION_SIGN; - senv.algorithm = SC_ALGORITHM_RSA; - senv.key_ref_len = 1; - senv.key_ref[0] = ref; - senv.flags = (SC_SEC_ENV_KEY_REF_PRESENT | SC_SEC_ENV_ALG_PRESENT); - r = sc_set_security_env(card, &senv, 0); - if (r) { - printf("Failed to set the security environment: %s\n", - sc_strerror (r)); - return -1; - } - - /* Perform the actual sign. */ - r = sc_compute_signature(card, indata, indatalen, - outdata, outdatalen); - if (r<0) { - printf("Signing failed: %s\n", sc_strerror (r)); - return -1; - } - util_hex_dump_asc(stdout, outdata, r, -1); - printf ("Done.\n"); - return 0; -usage: - printf ("Usage: pksign [MD5|SHA1|RMD160]\n"); - return -1; -#endif -} - - -static int do_pkdecrypt(int argc, char **argv) -{ - puts ("Not yet supported"); - return -1; -#if 0 - int i, ref, r; - u8 indata[128]; - size_t indatalen = sizeof indata; - u8 outdata[128]; - size_t outdatalen = sizeof outdata; - sc_security_env_t senv; - const char *s; - - if (argc != 2) - goto usage; - if (sscanf(argv[0], "%d", &ref) != 1 || ref < 0 || ref > 255) { - printf("Invalid key reference.\n"); - goto usage; - } - - if (argv[1][0] == '"') { - for (s=argv[1]+1, i = 0; - i < sizeof indata && *s && *s != '"'; i++) - indata[i] = *s++; - indatalen = i; - } else if (sc_hex_to_bin (argv[1], indata, &indatalen)) { - printf("Invalid data value.\n"); - goto usage; - } - - /* setup the security environment */ - memset (&senv, 0, sizeof senv); - senv.operation = SC_SEC_OPERATION_DECIPHER; - senv.algorithm = SC_ALGORITHM_RSA; - senv.key_ref_len = 1; - senv.key_ref[0] = ref; - senv.flags = (SC_SEC_ENV_KEY_REF_PRESENT | SC_SEC_ENV_ALG_PRESENT); - r = sc_set_security_env(card, &senv, 0); - if (r) { - printf("Failed to set the security environment: %s\n", - sc_strerror (r)); - return -1; - } - - /* perform the actual decryption */ - /* FIXME: It is pretty useless to to this test padding :-; */ - memmove(indata+(sizeof indata - indatalen), indata, indatalen); - memset(indata, 0, (sizeof indata - indatalen)); - indatalen = sizeof indata; - r = sc_decipher(card, indata, indatalen, outdata, outdatalen); - if (r<0) { - printf("Decryption failed: %s\n", sc_strerror (r)); - return -1; - } - util_hex_dump_asc (stdout, outdata, r, -1); - printf("Done.\n"); - return 0; -usage: - printf("Usage: pkdecrypt \n"); - return -1; -#endif -} - static int do_erase(int argc, char **argv) { @@ -1608,8 +1438,6 @@ static struct command cmds[] = { { "do_get", do_get_data, "get a data object" }, { "do_put", do_put_data, "put a data object" }, { "mkdir", do_mkdir, "create a DF" }, - { "pksign", do_pksign, "create a public key signature" }, - { "pkdecrypt", do_pkdecrypt, "perform a public key decryption" }, { "erase", do_erase, "erase card" }, { "random", do_random, "obtain N random bytes from card" }, { "quit", do_quit, "quit this program" }, From df20fe72e139e084381c8c7307d718fa5336145b Mon Sep 17 00:00:00 2001 From: martin Date: Fri, 13 Nov 2009 19:01:21 +0000 Subject: [PATCH 57/57] merge [3823:3844/trunk] git-svn-id: https://www.opensc-project.org/svnp/opensc/branches/martin/0.12@3845 c6295689-39f2-0310-b995-f0e70906c6a9 --- src/libopensc/card-default.c | 2 +- src/libopensc/errors.c | 3 +- src/libopensc/errors.h | 1 + src/pkcs11/framework-pkcs15.c | 6 +- src/tools/pkcs15-init.c | 123 +++++++++++++++++++++++++++++----- 5 files changed, 113 insertions(+), 22 deletions(-) diff --git a/src/libopensc/card-default.c b/src/libopensc/card-default.c index 2408b0ef..3207f38c 100644 --- a/src/libopensc/card-default.c +++ b/src/libopensc/card-default.c @@ -101,7 +101,7 @@ static int default_init(sc_card_t *card) { int r; - card->name = "Unidentified card"; + card->name = "Unsupported card"; card->drv_data = NULL; r = autodetect_class(card); if (r) { diff --git a/src/libopensc/errors.c b/src/libopensc/errors.c index 62d13a49..0f0fbe7e 100644 --- a/src/libopensc/errors.c +++ b/src/libopensc/errors.c @@ -89,7 +89,8 @@ const char *sc_strerror(int error) "Wrong padding", "Unsupported card", "Unable to load external module", - "EF offset too large" + "EF offset too large", + "Not implemented" }; const int int_base = -SC_ERROR_INTERNAL; const char *p15i_errors[] = { diff --git a/src/libopensc/errors.h b/src/libopensc/errors.h index b1f8dd6b..3362e799 100644 --- a/src/libopensc/errors.h +++ b/src/libopensc/errors.h @@ -90,6 +90,7 @@ extern "C" { #define SC_ERROR_WRONG_CARD -1413 #define SC_ERROR_CANNOT_LOAD_MODULE -1414 #define SC_ERROR_OFFSET_TOO_LARGE -1415 +#define SC_ERROR_NOT_IMPLEMENTED -1416 /* Relating to PKCS #15 init stuff */ #define SC_ERROR_PKCS15INIT -1500 diff --git a/src/pkcs11/framework-pkcs15.c b/src/pkcs11/framework-pkcs15.c index cd89a795..91946dd3 100644 --- a/src/pkcs11/framework-pkcs15.c +++ b/src/pkcs11/framework-pkcs15.c @@ -1735,13 +1735,13 @@ static CK_RV pkcs15_gen_keypair(struct sc_pkcs11_card *p11card, goto kpgen_done; } - /* Write the new public and private keys to the pkcs15 files */ - /* To support smartcards that require different keybobjects for signing and encryption */ + /* Write the new public and private keys to the pkcs15 files */ + /* To support smartcards that require different keybobjects for signing and encryption */ if (sc_pkcs15init_requires_restrictive_usage(p15card, &keygen_args.prkey_args, 0)) { sc_debug(context, "store split key required for this card", rv); /* second key is the signature keyobject */ rc = sc_pkcs15init_store_split_key(p15card, profile, &keygen_args.prkey_args, NULL, &priv_key_obj); - } + } else { rc = sc_pkcs15init_store_private_key(p15card, profile, &keygen_args.prkey_args, &priv_key_obj); } diff --git a/src/tools/pkcs15-init.c b/src/tools/pkcs15-init.c index 82f58ddc..9b849888 100644 --- a/src/tools/pkcs15-init.c +++ b/src/tools/pkcs15-init.c @@ -36,6 +36,13 @@ #include #include #include +#ifdef HAVE_STRING_H +#include +#endif +#include +#if OPENSSL_VERSION_NUMBER >= 0x00907000L +#include +#endif #include #include #include @@ -45,6 +52,12 @@ #include #include #include +#if OPENSSL_VERSION_NUMBER >= 0x10000000L +#include /* for OPENSSL_NO_EC */ +#ifndef OPENSSL_NO_EC +#include +#endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L */ #include #include #include @@ -89,6 +102,7 @@ static int do_store_data_object(struct sc_profile *profile); static void set_secrets(struct sc_profile *); static int init_keyargs(struct sc_pkcs15init_prkeyargs *); +static void init_gost_params(struct sc_pkcs15init_keyarg_gost_params *, EVP_PKEY *); static int get_new_pin(sc_ui_hints_t *, const char *, const char *, char **); static int get_pin_callback(struct sc_profile *profile, @@ -107,7 +121,7 @@ static int do_read_certificate(const char *, const char *, X509 **); static void parse_commandline(int argc, char **argv); static void read_options_file(const char *); static void ossl_print_errors(void); -static void set_userpin_ref(void); +static void set_userpin_ref(void); enum { @@ -132,7 +146,7 @@ enum { OPT_PUK2 = 0x10003, OPT_SERIAL = 0x10004, OPT_NO_SOPIN = 0x10005, - OPT_NO_PROMPT= 0x10006, + OPT_NO_PROMPT= 0x10006 }; const struct option options[] = { @@ -343,6 +357,9 @@ main(int argc, char **argv) unsigned int n; int r = 0; +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + OPENSSL_config(NULL); +#endif /* OpenSSL magic */ SSLeay_add_all_algorithms(); CRYPTO_malloc_init(); @@ -409,19 +426,7 @@ main(int argc, char **argv) if (verbose && action != ACTION_ASSERT_PRISTINE) printf("About to %s.\n", action_names[action]); -/* -{ - sc_path_t p1, p2, p3, p4; - sc_format_path("3F0050156666", &p1); p1.index = 0; p1.count = 50; - sc_format_path("3F0050157777", &p2); p2.index = 50; p2.count = 50; - sc_format_path("3F0050156666", &p3); p3.index = 200; p3.count = 50; - sc_format_path("3F0050156666", &p4); p4.index = 50; p4.count = 150; - r = sc_pkcs15init_remove_unusedspace(p15card, profile, &p1, NULL); - printf("sc_pkcs15init_add_unusedspace(): %d\n", r); - //r = sc_pkcs15init_add_unusedspace(p15card, profile, &p3, NULL); - //printf("sc_pkcs15init_add_unusedspace(): %d\n", r); -} -*/ + switch (action) { case ACTION_ASSERT_PRISTINE: /* skip printing error message */ @@ -763,6 +768,8 @@ do_store_private_key(struct sc_profile *profile) if ((r = do_convert_private_key(&args.key, pkey)) < 0) return r; + init_gost_params(&args.gost_params, pkey); + if (ncerts) { unsigned int usage; @@ -913,8 +920,11 @@ do_store_public_key(struct sc_profile *profile, EVP_PKEY *pkey) if (pkey == NULL) r = do_read_public_key(opt_infile, opt_format, &pkey); - if (r >= 0) + if (r >= 0) { r = do_convert_public_key(&args.key, pkey); + if (r >= 0) + init_gost_params(&args.gost_params, pkey); + } if (r >= 0) r = sc_pkcs15init_store_public_key(p15card, profile, &args, &dummy); @@ -1346,6 +1356,14 @@ do_generate_key(struct sc_profile *profile, const char *spec) keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_DSA; evp_algo = EVP_PKEY_DSA; spec += 3; + } else if (!strncasecmp(spec, "gost2001", strlen("gost2001"))) { + keygen_args.prkey_args.key.algorithm = SC_ALGORITHM_GOSTR3410; + keybits = SC_PKCS15_GOSTR3410_KEYSIZE; + /* FIXME: now only SC_PKCS15_PARAMSET_GOSTR3410_A */ + keygen_args.prkey_args.gost_params.gostr3410 = + SC_PKCS15_PARAMSET_GOSTR3410_A; + evp_algo = 0; /* FIXME */ + spec += strlen("gost2001"); } else { util_error("Unknown algorithm \"%s\"", spec); return SC_ERROR_INVALID_ARGUMENTS; @@ -1437,6 +1455,36 @@ static int init_keyargs(struct sc_pkcs15init_prkeyargs *args) return 0; } +static void +init_gost_params(struct sc_pkcs15init_keyarg_gost_params *params, EVP_PKEY *pkey) +{ +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) + EC_KEY *key; + + assert(pkey); + if (EVP_PKEY_id(pkey) == NID_id_GostR3410_2001) { + key = EVP_PKEY_get0(pkey); + assert(key); + assert(params); + assert(EC_KEY_get0_group(key)); + assert(EC_GROUP_get_curve_name(EC_KEY_get0_group(key)) > 0); + switch (EC_GROUP_get_curve_name(EC_KEY_get0_group(key))) { + case NID_id_GostR3410_2001_CryptoPro_A_ParamSet: + params->gostr3410 = SC_PKCS15_PARAMSET_GOSTR3410_A; + break; + case NID_id_GostR3410_2001_CryptoPro_B_ParamSet: + params->gostr3410 = SC_PKCS15_PARAMSET_GOSTR3410_B; + break; + case NID_id_GostR3410_2001_CryptoPro_C_ParamSet: + params->gostr3410 = SC_PKCS15_PARAMSET_GOSTR3410_C; + break; + } + } +#else + (void)params, (void)pkey; /* no warning */ +#endif +} + /* * Intern secrets given on the command line (mostly for testing) */ @@ -2076,7 +2124,7 @@ do_read_data_object(const char *name, u8 **out, size_t *outlen) } static int -do_convert_bignum(sc_pkcs15_bignum_t *dst, BIGNUM *src) +do_convert_bignum(sc_pkcs15_bignum_t *dst, const BIGNUM *src) { if (src == 0) return 0; @@ -2121,6 +2169,18 @@ static int do_convert_private_key(struct sc_pkcs15_prkey *key, EVP_PKEY *pk) DSA_free(src); break; } +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) + case NID_id_GostR3410_2001: { + struct sc_pkcs15_prkey_gostr3410 *dst = &key->u.gostr3410; + EC_KEY *src = EVP_PKEY_get0(pk); + + assert(src); + key->algorithm = SC_ALGORITHM_GOSTR3410; + assert(EC_KEY_get0_private_key(src)); + do_convert_bignum(&dst->d, EC_KEY_get0_private_key(src)); + break; + } +#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */ default: util_fatal("Unsupported key algorithm\n"); } @@ -2154,6 +2214,35 @@ static int do_convert_public_key(struct sc_pkcs15_pubkey *key, EVP_PKEY *pk) DSA_free(src); break; } +#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) + case NID_id_GostR3410_2001: { + struct sc_pkcs15_pubkey_gostr3410 *dst = &key->u.gostr3410; + EC_KEY *eckey = EVP_PKEY_get0(pk); + const EC_POINT *point; + BIGNUM *X, *Y; + int r = 0; + + assert(eckey); + point = EC_KEY_get0_public_key(eckey); + if (!point) + return SC_ERROR_INTERNAL; + X = BN_new(); + Y = BN_new(); + if (X && Y && EC_KEY_get0_group(eckey)) + r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey), + point, X, Y, NULL); + if (r == 1) { + do_convert_bignum(&dst->x, X); + do_convert_bignum(&dst->y, Y); + key->algorithm = SC_ALGORITHM_GOSTR3410; + } + BN_free(X); + BN_free(Y); + if (r != 1) + return SC_ERROR_INTERNAL; + break; + } +#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */ default: util_fatal("Unsupported key algorithm\n"); }