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:
parent
4196e9f156
commit
95a5ab0654
@ -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.
|
||||
|
@ -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)
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
@ -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");
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user