Merge pull request #444 from frankmorgner/pkcs11-error-handling

Improved error handling for PKCS#11 module
This commit is contained in:
viktorTarasov 2015-04-25 13:04:07 +02:00
commit c754e3f197
9 changed files with 64 additions and 19 deletions

View File

@ -572,6 +572,7 @@ iasecc_init_amos(struct sc_card *card)
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
}
static int
iasecc_mi_match(struct sc_card *card)
{
struct sc_context *ctx = card->ctx;
@ -2060,6 +2061,7 @@ iasecc_chv_change_pinpad(struct sc_card *card, unsigned reference, int *tries_le
}
#if 0
static int
iasecc_chv_set_pinpad(struct sc_card *card, unsigned char reference)
{
@ -2105,6 +2107,7 @@ iasecc_chv_set_pinpad(struct sc_card *card, unsigned char reference)
rv = iso_ops->pin_cmd(card, &pin_cmd, NULL);
LOG_FUNC_RETURN(ctx, rv);
}
#endif
static int

View File

@ -74,7 +74,6 @@ struct sc_atr_table {
/* Internal use only */
int _sc_add_reader(struct sc_context *ctx, struct sc_reader *reader);
int _sc_delete_reader(struct sc_context *ctx, struct sc_reader *reader);
int _sc_parse_atr(struct sc_reader *reader);
/* Add an ATR to the card driver's struct sc_atr_table */

View File

@ -77,6 +77,7 @@ sc_ctx_get_reader_by_name
sc_ctx_get_reader_count
sc_ctx_log_to_file
sc_ctx_use_reader
_sc_delete_reader
sc_decipher
sc_delete_file
sc_delete_record

View File

@ -286,6 +286,7 @@ struct sc_reader_driver {
#define SC_READER_CARD_INUSE 0x00000004
#define SC_READER_CARD_EXCLUSIVE 0x00000008
#define SC_READER_HAS_WAITING_AREA 0x00000010
#define SC_READER_REMOVED 0x00000020
/* reader capabilities */
#define SC_READER_CAP_DISPLAY 0x00000001
@ -802,6 +803,8 @@ sc_reader_t *sc_ctx_get_reader_by_id(sc_context_t *ctx, unsigned int id);
*/
unsigned int sc_ctx_get_reader_count(sc_context_t *ctx);
int _sc_delete_reader(sc_context_t *ctx, sc_reader_t *reader);
/**
* Redirects OpenSC debug log to the specified file
* @param ctx existing OpenSC context

View File

@ -951,6 +951,7 @@ static int pcsc_detect_readers(sc_context_t *ctx)
char *reader_buf = NULL, *reader_name;
const char *mszGroups = NULL;
int ret = SC_ERROR_INTERNAL;
size_t i;
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
@ -960,7 +961,13 @@ static int pcsc_detect_readers(sc_context_t *ctx)
goto out;
}
sc_log(ctx, "Probing pcsc readers");
/* temporarily mark all readers as removed */
for (i=0;i < sc_ctx_get_reader_count(ctx);i++) {
sc_reader_t *reader = sc_ctx_get_reader(ctx, i);
reader->flags |= SC_READER_REMOVED;
}
sc_log(ctx, "Probing PC/SC readers");
do {
if (gpriv->pcsc_ctx == -1) {
@ -974,6 +981,13 @@ static int pcsc_detect_readers(sc_context_t *ctx)
else {
rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL,
(LPDWORD) &reader_buf_size);
if (rv == SCARD_E_NO_SERVICE) {
gpriv->SCardReleaseContext(gpriv->pcsc_ctx);
gpriv->pcsc_ctx = -1;
gpriv->pcsc_wait_ctx = -1;
/* reconnecting below may may restart PC/SC service */
rv = SCARD_E_INVALID_HANDLE;
}
}
if (rv != SCARD_S_SUCCESS) {
if (rv != (LONG)SCARD_E_INVALID_HANDLE) {
@ -982,7 +996,7 @@ static int pcsc_detect_readers(sc_context_t *ctx)
goto out;
}
sc_log(ctx, "Establish pcsc context");
sc_log(ctx, "Establish PC/SC context");
rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER,
NULL, NULL, &gpriv->pcsc_ctx);
@ -1009,28 +1023,28 @@ static int pcsc_detect_readers(sc_context_t *ctx)
goto out;
}
for (reader_name = reader_buf; *reader_name != '\x0'; reader_name += strlen(reader_name) + 1) {
sc_reader_t *reader = NULL;
sc_reader_t *reader = NULL, *old_reader;
struct pcsc_private_data *priv = NULL;
unsigned int i;
int found = 0;
for (i=0;i < sc_ctx_get_reader_count(ctx) && !found;i++) {
sc_reader_t *reader2 = sc_ctx_get_reader(ctx, i);
if (reader2 == NULL) {
old_reader = sc_ctx_get_reader(ctx, i);
if (old_reader == NULL) {
ret = SC_ERROR_INTERNAL;
goto err1;
}
if (!strcmp(reader2->name, reader_name)) {
if (!strcmp(old_reader->name, reader_name)) {
found = 1;
}
}
/* Reader already available, skip */
if (found) {
old_reader->flags &= ~SC_READER_REMOVED;
continue;
}
sc_log(ctx, "Found new pcsc reader '%s'", reader_name);
sc_log(ctx, "Found new PC/SC reader '%s'", reader_name);
if ((reader = calloc(1, sizeof(sc_reader_t))) == NULL) {
ret = SC_ERROR_OUT_OF_MEMORY;

View File

@ -120,17 +120,17 @@ static CK_RV sc_pkcs11_close_session(CK_SESSION_HANDLE hSession)
* the global lock held */
CK_RV sc_pkcs11_close_all_sessions(CK_SLOT_ID slotID)
{
CK_RV rv = CKR_OK;
CK_RV rv = CKR_OK, error;
struct sc_pkcs11_session *session;
unsigned int i;
sc_log(context, "real C_CloseAllSessions(0x%lx) %d", slotID, list_size(&sessions));
for (i = 0; i < list_size(&sessions); i++) {
session = list_get_at(&sessions, i);
if (session->slot->id == slotID)
if ((rv = sc_pkcs11_close_session(session->handle)) != CKR_OK)
return rv;
if ((error = sc_pkcs11_close_session(session->handle)) != CKR_OK)
rv = error;
}
return CKR_OK;
return rv;
}
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)

View File

@ -20,6 +20,7 @@
*/
#include "config.h"
#include "libopensc/opensc.h"
#include <string.h>
#include <stdlib.h>
@ -100,6 +101,15 @@ CK_RV create_slot(sc_reader_t *reader)
return CKR_OK;
}
void delete_slot(struct sc_pkcs11_slot *slot)
{
if (slot) {
list_destroy(&slot->objects);
list_delete(&virtual_slots, slot);
free(slot);
}
}
/* create slots associated with a reader, called whenever a reader is seen. */
CK_RV initialize_reader(sc_reader_t *reader)
@ -330,9 +340,19 @@ card_detect_all(void)
/* Detect cards in all initialized readers */
for (i=0; i< sc_ctx_get_reader_count(context); i++) {
sc_reader_t *reader = sc_ctx_get_reader(context, i);
if (!reader_get_slot(reader))
initialize_reader(reader);
card_detect(sc_ctx_get_reader(context, i));
if (reader->flags & SC_READER_REMOVED) {
struct sc_pkcs11_slot *slot;
card_removed(reader);
while ((slot = reader_get_slot(reader))) {
delete_slot(slot);
}
_sc_delete_reader(context, reader);
i--;
} else {
if (!reader_get_slot(reader))
initialize_reader(reader);
card_detect(sc_ctx_get_reader(context, i));
}
}
sc_log(context, "All cards detected");
return CKR_OK;
@ -420,7 +440,7 @@ CK_RV slot_token_removed(CK_SLOT_ID id)
/* Release framework stuff */
if (slot->card != NULL) {
if (slot->fw_data != NULL &&
slot->card->framework != NULL && slot->card->framework->release_token != NULL)
slot->card->framework != NULL && slot->card->framework->release_token != NULL)
slot->card->framework->release_token(slot->card, slot->fw_data);
}
@ -446,7 +466,7 @@ CK_RV slot_find_changed(CK_SLOT_ID_PTR idp, int mask)
sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
sc_log(context, "slot 0x%lx token: %d events: 0x%02X",slot->id, (slot->slot_info.flags & CKF_TOKEN_PRESENT), slot->events);
if ((slot->events & SC_EVENT_CARD_INSERTED)
&& !(slot->slot_info.flags & CKF_TOKEN_PRESENT)) {
&& !(slot->slot_info.flags & CKF_TOKEN_PRESENT)) {
/* If a token has not been initialized, clear the inserted event */
slot->events &= ~SC_EVENT_CARD_INSERTED;
}

View File

@ -646,7 +646,7 @@ myeid_generate_key(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
memcpy(pubkey->u.rsa.modulus.data, raw_pubkey, pubkey->u.rsa.modulus.len);
}
else if (object->type == SC_PKCS15_TYPE_PRKEY_EC) {
struct sc_ec_parameters *ecparams = (struct sc_pkcs15_ec_parameters *)key_info->params.data;
struct sc_ec_parameters *ecparams = (struct sc_ec_parameters *)key_info->params.data;
sc_log(ctx, "curve '%s', len %i, oid '%s'", ecparams->named_curve, ecparams->field_length, sc_dump_oid(&(ecparams->id)));
pubkey->algorithm = SC_ALGORITHM_EC;

View File

@ -803,6 +803,8 @@ static void print_ssh_key(FILE *outf, const char * alg, struct sc_pkcs15_object
if (opt_rfc4716) {
r = sc_base64_encode(buf, len, uu, 2*len, 64);
if (r < 0)
return;
fprintf(outf,"---- BEGIN SSH2 PUBLIC KEY ----\n");
@ -815,6 +817,9 @@ static void print_ssh_key(FILE *outf, const char * alg, struct sc_pkcs15_object
// Old style openssh - [<quote protected options> <whitespace> <keytype> <whitespace> <key> [<whitespace> anything else]
//
r = sc_base64_encode(buf, len, uu, 2*len, 0);
if (r < 0)
return;
if (obj->label && strlen(obj->label))
fprintf(outf,"ssh-%s %s %s\n", alg, uu, obj->label);
else