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
This commit is contained in:
martin 2009-10-22 08:59:59 +00:00
parent 4196e9f156
commit 95a5ab0654
15 changed files with 188 additions and 159 deletions

View File

@ -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.

View File

@ -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)
#

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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; i<SC_PKCS15_MAX_PINS; i++) {
if (p15card->pin_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; i<SC_PKCS15_MAX_PINS && p15card->pin_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; i<SC_PKCS15_MAX_PINS && p15card->pin_cache[i] != NULL; i++)
sc_mem_clear(p15card->pin_cache[i]->pin, p15card->pin_cache[i]->len);
}

View File

@ -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");

View File

@ -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; i<SC_PKCS15_MAX_PINS && p15card->pin_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) {

View File

@ -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,

View File

@ -26,6 +26,9 @@
#include <openssl/crypto.h> /* for OPENSSL_cleanse */
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include "internal.h"
#include <stdio.h>
#include <ctype.h>
@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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;
};

View File

@ -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) {