pkcs11: #162,#370,#115,#413: reselect application DF issue
Limit the number of cases when applicated re-selection of application DF to strict minimum. I.e. only when pkcs11 login session is not locked and private key PKCS#15 object do not contain the 'path' attribute.
This commit is contained in:
parent
cb54ebf747
commit
ca08e97ab7
|
@ -492,10 +492,10 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);
|
r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);
|
||||||
if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
|
if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED)
|
||||||
if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS)
|
if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS)
|
||||||
r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);
|
r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);
|
||||||
}
|
|
||||||
sc_mem_clear(buf, sizeof(buf));
|
sc_mem_clear(buf, sizeof(buf));
|
||||||
sc_unlock(p15card->card);
|
sc_unlock(p15card->card);
|
||||||
LOG_TEST_RET(ctx, r, "sc_compute_signature() failed");
|
LOG_TEST_RET(ctx, r, "sc_compute_signature() failed");
|
||||||
|
|
|
@ -3022,7 +3022,7 @@ pkcs15_cert_cmp_attribute(struct sc_pkcs11_session *session,
|
||||||
struct pkcs15_cert_object *cert = (struct pkcs15_cert_object*) object;
|
struct pkcs15_cert_object *cert = (struct pkcs15_cert_object*) object;
|
||||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||||
struct pkcs15_fw_data *fw_data = NULL;
|
struct pkcs15_fw_data *fw_data = NULL;
|
||||||
unsigned char *data = NULL, *_data = NULL;
|
const unsigned char *data = NULL, *_data = NULL;
|
||||||
size_t len, _len;
|
size_t len, _len;
|
||||||
|
|
||||||
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
fw_data = (struct pkcs15_fw_data *) p11card->fws_data[session->slot->fw_data_idx];
|
||||||
|
@ -3292,7 +3292,7 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj,
|
||||||
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;
|
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;
|
||||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||||
struct pkcs15_fw_data *fw_data = NULL;
|
struct pkcs15_fw_data *fw_data = NULL;
|
||||||
int rv, flags = 0;
|
int rv, flags = 0, prkey_has_path = 0;
|
||||||
unsigned sign_flags = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
|
unsigned sign_flags = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
|
||||||
| SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
| SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
|
||||||
|
|
||||||
|
@ -3308,6 +3308,9 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj,
|
||||||
if (prkey == NULL)
|
if (prkey == NULL)
|
||||||
return CKR_KEY_FUNCTION_NOT_PERMITTED;
|
return CKR_KEY_FUNCTION_NOT_PERMITTED;
|
||||||
|
|
||||||
|
if (prkey->prv_info->path.len || prkey->prv_info->path.aid.len)
|
||||||
|
prkey_has_path = 1;
|
||||||
|
|
||||||
switch (pMechanism->mechanism) {
|
switch (pMechanism->mechanism) {
|
||||||
case CKM_RSA_PKCS:
|
case CKM_RSA_PKCS:
|
||||||
flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE;
|
flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE;
|
||||||
|
@ -3368,17 +3371,20 @@ pkcs15_prkey_sign(struct sc_pkcs11_session *session, void *obj,
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return sc_to_cryptoki_error(rv, "C_Sign");
|
return sc_to_cryptoki_error(rv, "C_Sign");
|
||||||
|
|
||||||
if (!sc_pkcs11_conf.lock_login) {
|
|
||||||
rv = reselect_app_df(fw_data->p15_card);
|
|
||||||
if (rv < 0) {
|
|
||||||
sc_unlock(p11card->card);
|
|
||||||
return sc_to_cryptoki_error(rv, "C_Sign");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_log(context, "Selected flags %X. Now computing signature for %d bytes. %d bytes reserved.", flags, ulDataLen, *pulDataLen);
|
sc_log(context, "Selected flags %X. Now computing signature for %d bytes. %d bytes reserved.", flags, ulDataLen, *pulDataLen);
|
||||||
rv = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags,
|
rv = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||||
pData, ulDataLen, pSignature, *pulDataLen);
|
pData, ulDataLen, pSignature, *pulDataLen);
|
||||||
|
if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path) {
|
||||||
|
/* If private key PKCS#15 object do not have 'path' attribute,
|
||||||
|
* and if PKCS#11 login session is not locked,
|
||||||
|
* the compute signature could fail because of concurent access to the card
|
||||||
|
* by other application that could change the current DF.
|
||||||
|
* In this particular case try to 'reselect' application DF.
|
||||||
|
*/
|
||||||
|
if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS)
|
||||||
|
rv = sc_pkcs15_compute_signature(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||||
|
pData, ulDataLen, pSignature, *pulDataLen);
|
||||||
|
}
|
||||||
|
|
||||||
sc_unlock(p11card->card);
|
sc_unlock(p11card->card);
|
||||||
|
|
||||||
|
@ -3403,7 +3409,7 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
|
||||||
struct pkcs15_fw_data *fw_data = NULL;
|
struct pkcs15_fw_data *fw_data = NULL;
|
||||||
struct pkcs15_prkey_object *prkey;
|
struct pkcs15_prkey_object *prkey;
|
||||||
unsigned char decrypted[256]; /* FIXME: Will not work for keys above 2048 bits */
|
unsigned char decrypted[256]; /* FIXME: Will not work for keys above 2048 bits */
|
||||||
int buff_too_small, rv, flags = 0;
|
int buff_too_small, rv, flags = 0, prkey_has_path = 0;
|
||||||
|
|
||||||
sc_log(context, "Initiating decryption.");
|
sc_log(context, "Initiating decryption.");
|
||||||
|
|
||||||
|
@ -3418,6 +3424,9 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
|
||||||
if (prkey == NULL)
|
if (prkey == NULL)
|
||||||
return CKR_KEY_FUNCTION_NOT_PERMITTED;
|
return CKR_KEY_FUNCTION_NOT_PERMITTED;
|
||||||
|
|
||||||
|
if (prkey->prv_info->path.len || prkey->prv_info->path.aid.len)
|
||||||
|
prkey_has_path = 1;
|
||||||
|
|
||||||
/* Select the proper padding mechanism */
|
/* Select the proper padding mechanism */
|
||||||
switch (pMechanism->mechanism) {
|
switch (pMechanism->mechanism) {
|
||||||
case CKM_RSA_PKCS:
|
case CKM_RSA_PKCS:
|
||||||
|
@ -3434,17 +3443,13 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *session, void *obj,
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return sc_to_cryptoki_error(rv, "C_Decrypt");
|
return sc_to_cryptoki_error(rv, "C_Decrypt");
|
||||||
|
|
||||||
if (!sc_pkcs11_conf.lock_login) {
|
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||||
rv = reselect_app_df(fw_data->p15_card);
|
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted));
|
||||||
if (rv < 0) {
|
|
||||||
sc_unlock(p11card->card);
|
|
||||||
return sc_to_cryptoki_error(rv, "C_Decrypt");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj,
|
if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path)
|
||||||
flags, pEncryptedData, ulEncryptedDataLen,
|
if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS)
|
||||||
decrypted, sizeof(decrypted));
|
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||||
|
pEncryptedData, ulEncryptedDataLen, decrypted, sizeof(decrypted));
|
||||||
|
|
||||||
sc_unlock(p11card->card);
|
sc_unlock(p11card->card);
|
||||||
|
|
||||||
|
@ -3474,7 +3479,7 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj,
|
||||||
struct sc_pkcs11_card *p11card = session->slot->card;
|
struct sc_pkcs11_card *p11card = session->slot->card;
|
||||||
struct pkcs15_fw_data *fw_data = NULL;
|
struct pkcs15_fw_data *fw_data = NULL;
|
||||||
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;
|
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;
|
||||||
int need_unlock = 0;
|
int need_unlock = 0, prkey_has_path = 0;
|
||||||
int rv, flags = 0;
|
int rv, flags = 0;
|
||||||
CK_BYTE_PTR pSeedData = NULL;
|
CK_BYTE_PTR pSeedData = NULL;
|
||||||
CK_ULONG ulSeedDataLen = 0;
|
CK_ULONG ulSeedDataLen = 0;
|
||||||
|
@ -3494,19 +3499,14 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj,
|
||||||
if (prkey == NULL)
|
if (prkey == NULL)
|
||||||
return CKR_KEY_FUNCTION_NOT_PERMITTED;
|
return CKR_KEY_FUNCTION_NOT_PERMITTED;
|
||||||
|
|
||||||
|
if (prkey->prv_info->path.len || prkey->prv_info->path.aid.len)
|
||||||
|
prkey_has_path = 1;
|
||||||
|
|
||||||
if (pData != NULL && *pulDataLen > 0) { /* TODO DEE only test for NULL? */
|
if (pData != NULL && *pulDataLen > 0) { /* TODO DEE only test for NULL? */
|
||||||
need_unlock = 1;
|
need_unlock = 1;
|
||||||
rv = sc_lock(p11card->card);
|
rv = sc_lock(p11card->card);
|
||||||
if (rv < 0)
|
if (rv < 0)
|
||||||
return sc_to_cryptoki_error(rv, "C_DeriveKey");
|
return sc_to_cryptoki_error(rv, "C_DeriveKey");
|
||||||
|
|
||||||
if (!sc_pkcs11_conf.lock_login) {
|
|
||||||
rv = reselect_app_df(fw_data->p15_card);
|
|
||||||
if (rv < 0) {
|
|
||||||
sc_unlock(p11card->card);
|
|
||||||
return sc_to_cryptoki_error(rv, "C_DeriveKey");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO DEE This may not be the place to get the parameters,
|
/* TODO DEE This may not be the place to get the parameters,
|
||||||
|
@ -3523,13 +3523,17 @@ pkcs15_prkey_derive(struct sc_pkcs11_session *session, void *obj,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = sc_pkcs15_derive(fw_data->p15_card, prkey->prv_p15obj,
|
rv = sc_pkcs15_derive(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||||
flags, pSeedData, ulSeedDataLen,
|
pSeedData, ulSeedDataLen, pData, pulDataLen);
|
||||||
pData, pulDataLen);
|
if (rv < 0 && !sc_pkcs11_conf.lock_login && !prkey_has_path && need_unlock)
|
||||||
|
if (reselect_app_df(fw_data->p15_card) == SC_SUCCESS)
|
||||||
|
rv = sc_pkcs15_derive(fw_data->p15_card, prkey->prv_p15obj, flags,
|
||||||
|
pSeedData, ulSeedDataLen, pData, pulDataLen);
|
||||||
|
|
||||||
/* this may have been a request for size */
|
/* this may have been a request for size */
|
||||||
|
|
||||||
if (need_unlock)
|
if (need_unlock)
|
||||||
sc_unlock(p11card->card);
|
sc_unlock(p11card->card);
|
||||||
|
|
||||||
sc_log(context, "Derivation complete. Result %d.", rv);
|
sc_log(context, "Derivation complete. Result %d.", rv);
|
||||||
|
|
||||||
|
|
|
@ -63,8 +63,7 @@ int util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
|
||||||
reader = found;
|
reader = found;
|
||||||
} else {
|
} else {
|
||||||
if (sc_ctx_get_reader_count(ctx) == 0) {
|
if (sc_ctx_get_reader_count(ctx) == 0) {
|
||||||
fprintf(stderr,
|
fprintf(stderr, "No smart card readers found.\n");
|
||||||
"No smart card readers found.\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!reader_id) {
|
if (!reader_id) {
|
||||||
|
@ -84,6 +83,7 @@ int util_connect_card(sc_context_t *ctx, sc_card_t **cardp,
|
||||||
unsigned char atr_buf[SC_MAX_ATR_SIZE * 3];
|
unsigned char atr_buf[SC_MAX_ATR_SIZE * 3];
|
||||||
size_t atr_buf_len = sizeof(atr_buf);
|
size_t atr_buf_len = sizeof(atr_buf);
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
if (sc_hex_to_bin(reader_id, atr_buf, &atr_buf_len) == SC_SUCCESS) {
|
if (sc_hex_to_bin(reader_id, atr_buf, &atr_buf_len) == SC_SUCCESS) {
|
||||||
/* Loop readers, looking for a card with ATR */
|
/* Loop readers, looking for a card with ATR */
|
||||||
for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) {
|
for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) {
|
||||||
|
|
Loading…
Reference in New Issue