Merge pull request #444 from frankmorgner/pkcs11-error-handling
Improved error handling for PKCS#11 module
This commit is contained in:
commit
c754e3f197
|
@ -572,6 +572,7 @@ iasecc_init_amos(struct sc_card *card)
|
||||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
iasecc_mi_match(struct sc_card *card)
|
iasecc_mi_match(struct sc_card *card)
|
||||||
{
|
{
|
||||||
struct sc_context *ctx = card->ctx;
|
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
|
static int
|
||||||
iasecc_chv_set_pinpad(struct sc_card *card, unsigned char reference)
|
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);
|
rv = iso_ops->pin_cmd(card, &pin_cmd, NULL);
|
||||||
LOG_FUNC_RETURN(ctx, rv);
|
LOG_FUNC_RETURN(ctx, rv);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -74,7 +74,6 @@ struct sc_atr_table {
|
||||||
|
|
||||||
/* Internal use only */
|
/* Internal use only */
|
||||||
int _sc_add_reader(struct sc_context *ctx, struct sc_reader *reader);
|
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);
|
int _sc_parse_atr(struct sc_reader *reader);
|
||||||
|
|
||||||
/* Add an ATR to the card driver's struct sc_atr_table */
|
/* Add an ATR to the card driver's struct sc_atr_table */
|
||||||
|
|
|
@ -77,6 +77,7 @@ sc_ctx_get_reader_by_name
|
||||||
sc_ctx_get_reader_count
|
sc_ctx_get_reader_count
|
||||||
sc_ctx_log_to_file
|
sc_ctx_log_to_file
|
||||||
sc_ctx_use_reader
|
sc_ctx_use_reader
|
||||||
|
_sc_delete_reader
|
||||||
sc_decipher
|
sc_decipher
|
||||||
sc_delete_file
|
sc_delete_file
|
||||||
sc_delete_record
|
sc_delete_record
|
||||||
|
|
|
@ -286,6 +286,7 @@ struct sc_reader_driver {
|
||||||
#define SC_READER_CARD_INUSE 0x00000004
|
#define SC_READER_CARD_INUSE 0x00000004
|
||||||
#define SC_READER_CARD_EXCLUSIVE 0x00000008
|
#define SC_READER_CARD_EXCLUSIVE 0x00000008
|
||||||
#define SC_READER_HAS_WAITING_AREA 0x00000010
|
#define SC_READER_HAS_WAITING_AREA 0x00000010
|
||||||
|
#define SC_READER_REMOVED 0x00000020
|
||||||
|
|
||||||
/* reader capabilities */
|
/* reader capabilities */
|
||||||
#define SC_READER_CAP_DISPLAY 0x00000001
|
#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);
|
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
|
* Redirects OpenSC debug log to the specified file
|
||||||
* @param ctx existing OpenSC context
|
* @param ctx existing OpenSC context
|
||||||
|
|
|
@ -951,6 +951,7 @@ static int pcsc_detect_readers(sc_context_t *ctx)
|
||||||
char *reader_buf = NULL, *reader_name;
|
char *reader_buf = NULL, *reader_name;
|
||||||
const char *mszGroups = NULL;
|
const char *mszGroups = NULL;
|
||||||
int ret = SC_ERROR_INTERNAL;
|
int ret = SC_ERROR_INTERNAL;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
|
SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
|
||||||
|
|
||||||
|
@ -960,7 +961,13 @@ static int pcsc_detect_readers(sc_context_t *ctx)
|
||||||
goto out;
|
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 {
|
do {
|
||||||
if (gpriv->pcsc_ctx == -1) {
|
if (gpriv->pcsc_ctx == -1) {
|
||||||
|
@ -974,6 +981,13 @@ static int pcsc_detect_readers(sc_context_t *ctx)
|
||||||
else {
|
else {
|
||||||
rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL,
|
rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL,
|
||||||
(LPDWORD) &reader_buf_size);
|
(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 != SCARD_S_SUCCESS) {
|
||||||
if (rv != (LONG)SCARD_E_INVALID_HANDLE) {
|
if (rv != (LONG)SCARD_E_INVALID_HANDLE) {
|
||||||
|
@ -982,7 +996,7 @@ static int pcsc_detect_readers(sc_context_t *ctx)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_log(ctx, "Establish pcsc context");
|
sc_log(ctx, "Establish PC/SC context");
|
||||||
|
|
||||||
rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER,
|
rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER,
|
||||||
NULL, NULL, &gpriv->pcsc_ctx);
|
NULL, NULL, &gpriv->pcsc_ctx);
|
||||||
|
@ -1009,28 +1023,28 @@ static int pcsc_detect_readers(sc_context_t *ctx)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
for (reader_name = reader_buf; *reader_name != '\x0'; reader_name += strlen(reader_name) + 1) {
|
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;
|
struct pcsc_private_data *priv = NULL;
|
||||||
unsigned int i;
|
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
for (i=0;i < sc_ctx_get_reader_count(ctx) && !found;i++) {
|
for (i=0;i < sc_ctx_get_reader_count(ctx) && !found;i++) {
|
||||||
sc_reader_t *reader2 = sc_ctx_get_reader(ctx, i);
|
old_reader = sc_ctx_get_reader(ctx, i);
|
||||||
if (reader2 == NULL) {
|
if (old_reader == NULL) {
|
||||||
ret = SC_ERROR_INTERNAL;
|
ret = SC_ERROR_INTERNAL;
|
||||||
goto err1;
|
goto err1;
|
||||||
}
|
}
|
||||||
if (!strcmp(reader2->name, reader_name)) {
|
if (!strcmp(old_reader->name, reader_name)) {
|
||||||
found = 1;
|
found = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reader already available, skip */
|
/* Reader already available, skip */
|
||||||
if (found) {
|
if (found) {
|
||||||
|
old_reader->flags &= ~SC_READER_REMOVED;
|
||||||
continue;
|
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) {
|
if ((reader = calloc(1, sizeof(sc_reader_t))) == NULL) {
|
||||||
ret = SC_ERROR_OUT_OF_MEMORY;
|
ret = SC_ERROR_OUT_OF_MEMORY;
|
||||||
|
|
|
@ -120,17 +120,17 @@ static CK_RV sc_pkcs11_close_session(CK_SESSION_HANDLE hSession)
|
||||||
* the global lock held */
|
* the global lock held */
|
||||||
CK_RV sc_pkcs11_close_all_sessions(CK_SLOT_ID slotID)
|
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;
|
struct sc_pkcs11_session *session;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
sc_log(context, "real C_CloseAllSessions(0x%lx) %d", slotID, list_size(&sessions));
|
sc_log(context, "real C_CloseAllSessions(0x%lx) %d", slotID, list_size(&sessions));
|
||||||
for (i = 0; i < list_size(&sessions); i++) {
|
for (i = 0; i < list_size(&sessions); i++) {
|
||||||
session = list_get_at(&sessions, i);
|
session = list_get_at(&sessions, i);
|
||||||
if (session->slot->id == slotID)
|
if (session->slot->id == slotID)
|
||||||
if ((rv = sc_pkcs11_close_session(session->handle)) != CKR_OK)
|
if ((error = sc_pkcs11_close_session(session->handle)) != CKR_OK)
|
||||||
return rv;
|
rv = error;
|
||||||
}
|
}
|
||||||
return CKR_OK;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)
|
CK_RV C_CloseSession(CK_SESSION_HANDLE hSession)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "libopensc/opensc.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -100,6 +101,15 @@ CK_RV create_slot(sc_reader_t *reader)
|
||||||
return CKR_OK;
|
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. */
|
/* create slots associated with a reader, called whenever a reader is seen. */
|
||||||
CK_RV initialize_reader(sc_reader_t *reader)
|
CK_RV initialize_reader(sc_reader_t *reader)
|
||||||
|
@ -330,10 +340,20 @@ card_detect_all(void)
|
||||||
/* Detect cards in all initialized readers */
|
/* Detect cards in all initialized readers */
|
||||||
for (i=0; i< sc_ctx_get_reader_count(context); i++) {
|
for (i=0; i< sc_ctx_get_reader_count(context); i++) {
|
||||||
sc_reader_t *reader = sc_ctx_get_reader(context, i);
|
sc_reader_t *reader = 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))
|
if (!reader_get_slot(reader))
|
||||||
initialize_reader(reader);
|
initialize_reader(reader);
|
||||||
card_detect(sc_ctx_get_reader(context, i));
|
card_detect(sc_ctx_get_reader(context, i));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sc_log(context, "All cards detected");
|
sc_log(context, "All cards detected");
|
||||||
return CKR_OK;
|
return CKR_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
memcpy(pubkey->u.rsa.modulus.data, raw_pubkey, pubkey->u.rsa.modulus.len);
|
||||||
}
|
}
|
||||||
else if (object->type == SC_PKCS15_TYPE_PRKEY_EC) {
|
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)));
|
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;
|
pubkey->algorithm = SC_ALGORITHM_EC;
|
||||||
|
|
|
@ -803,6 +803,8 @@ static void print_ssh_key(FILE *outf, const char * alg, struct sc_pkcs15_object
|
||||||
|
|
||||||
if (opt_rfc4716) {
|
if (opt_rfc4716) {
|
||||||
r = sc_base64_encode(buf, len, uu, 2*len, 64);
|
r = sc_base64_encode(buf, len, uu, 2*len, 64);
|
||||||
|
if (r < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
fprintf(outf,"---- BEGIN SSH2 PUBLIC KEY ----\n");
|
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]
|
// Old style openssh - [<quote protected options> <whitespace> <keytype> <whitespace> <key> [<whitespace> anything else]
|
||||||
//
|
//
|
||||||
r = sc_base64_encode(buf, len, uu, 2*len, 0);
|
r = sc_base64_encode(buf, len, uu, 2*len, 0);
|
||||||
|
if (r < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
if (obj->label && strlen(obj->label))
|
if (obj->label && strlen(obj->label))
|
||||||
fprintf(outf,"ssh-%s %s %s\n", alg, uu, obj->label);
|
fprintf(outf,"ssh-%s %s %s\n", alg, uu, obj->label);
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue