- Register only those mechanisms the card actually supports

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@783 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
okir 2002-12-17 20:16:31 +00:00
parent 0c16b3d887
commit 647d4bcdef
3 changed files with 101 additions and 48 deletions

View File

@ -1486,22 +1486,76 @@ cache_pin(void *p, int user, const void *pin, size_t len)
int
register_mechanisms(struct sc_pkcs11_card *p11card)
{
sc_card_t *card = p11card->card;
sc_algorithm_info_t *alg_info;
CK_MECHANISM_INFO mech_info;
int rc;
sc_pkcs11_mechanism_type_t *mt;
unsigned int num;
int rc, flags = 0;
/* Register generic mechanisms */
sc_pkcs11_register_generic_mechanisms(p11card);
mech_info.flags = CKF_HW | CKF_SIGN | CKF_UNWRAP;
mech_info.ulMinKeySize = 512;
mech_info.ulMaxKeySize = 2048;
rc = sc_pkcs11_register_mechanism(p11card,
sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS, &mech_info, CKK_RSA, NULL));
if (rc != CKR_OK)
return rc;
rc = sc_pkcs11_register_mechanism(p11card,
sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509, &mech_info, CKK_RSA, NULL));
if (rc != CKR_OK)
return rc;
mech_info.ulMinKeySize = ~0;
mech_info.ulMaxKeySize = 0;
/* Register generic mechanisms (e.g. digest mechanisms, software encryption/
* decryption stuff, and hash+sign algorithms */
return sc_pkcs11_register_generic_mechanisms(p11card);
/* For now, we just OR all the algorithm specific
* flags, based on the assumption that cards don't
* support different modes for different key sizes
*/
num = card->algorithm_count;
alg_info = card->algorithms;
while (num--) {
if (alg_info->algorithm != SC_ALGORITHM_RSA)
continue;
if (alg_info->key_length < mech_info.ulMinKeySize)
mech_info.ulMinKeySize = alg_info->key_length;
if (alg_info->key_length > mech_info.ulMaxKeySize)
mech_info.ulMaxKeySize = alg_info->key_length;
flags |= alg_info->flags;
alg_info++;
}
/* Check if we support raw RSA */
if (flags & SC_ALGORITHM_RSA_RAW) {
mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_X_509,
&mech_info, CKK_RSA, NULL);
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
}
/* Check for PKCS1 */
if (flags & SC_ALGORITHM_RSA_PAD_PKCS1) {
mt = sc_pkcs11_new_fw_mechanism(CKM_RSA_PKCS,
&mech_info, CKK_RSA, NULL);
rc = sc_pkcs11_register_mechanism(p11card, mt);
if (rc != CKR_OK)
return rc;
/* if the driver doesn't say what hashes it supports,
* claim we will do all of them */
if (!(flags & SC_ALGORITHM_RSA_HASHES))
flags |= SC_ALGORITHM_RSA_HASHES;
if (flags & SC_ALGORITHM_RSA_HASH_SHA1)
sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_SHA1_RSA_PKCS, CKM_SHA_1, mt);
if (flags & SC_ALGORITHM_RSA_HASH_MD5)
sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_MD5_RSA_PKCS, CKM_MD5, mt);
if (flags & SC_ALGORITHM_RSA_HASH_RIPEMD160)
sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, mt);
#if 0
/* Does this correspond to any defined CKM_XXX value? */
if (flags & SC_ALGORITHM_RSA_HASH_MD5_SHA1)
sc_pkcs11_register_sign_and_hash_mechanism(p11card,
CKM_XXX_RSA_PKCS, CKM_XXX, mt);
#endif
}
return CKR_OK;
}

View File

@ -414,48 +414,44 @@ sc_pkcs11_new_fw_mechanism(CK_MECHANISM_TYPE mech,
}
/*
* Support for sign+hash
*/
static struct hash_signature_info sig_hash_mechs[] = {
{ CKM_SHA1_RSA_PKCS, CKM_SHA_1, CKM_RSA_PKCS },
{ CKM_MD5_RSA_PKCS, CKM_MD5, CKM_RSA_PKCS },
{ CKM_RIPEMD160_RSA_PKCS, CKM_RIPEMD160, CKM_RSA_PKCS },
{ 0 }
};
/*
* Register generic mechanisms, i.e.
* - software only algorithms such as digests
* - sign+hash mechanisms that use the card's
* signature ops and a generic digest mechanism
* Register generic mechanisms
*/
CK_RV
sc_pkcs11_register_generic_mechanisms(struct sc_pkcs11_card *p11card)
{
struct hash_signature_info *info;
#ifdef HAVE_OPENSSL
sc_pkcs11_register_openssl_mechanisms(p11card);
#endif
for (info = sig_hash_mechs; info->mech; info++) {
sc_pkcs11_mechanism_type_t *hash_type, *sign_type, *new_type;
hash_type = sc_pkcs11_find_mechanism(p11card, info->hash_mech, 0);
sign_type = sc_pkcs11_find_mechanism(p11card, info->sign_mech, CKF_SIGN);
if (!hash_type || !sign_type)
continue;
info->sign_type = sign_type;
info->hash_type = hash_type;
new_type = sc_pkcs11_new_fw_mechanism(info->mech,
&sign_type->mech_info,
sign_type->key_type,
info);
if (new_type)
sc_pkcs11_register_mechanism(p11card, new_type);
}
return CKR_OK;
}
/*
* Register a sign+hash algorithm derived from an algorithm supported
* by the token + a software hash mechanism
*/
CK_RV
sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *p11card,
CK_MECHANISM_TYPE mech,
CK_MECHANISM_TYPE hash_mech,
sc_pkcs11_mechanism_type_t *sign_type)
{
sc_pkcs11_mechanism_type_t *hash_type, *new_type;
struct hash_signature_info *info;
if (!(hash_type = sc_pkcs11_find_mechanism(p11card, hash_mech, CKF_DIGEST)))
return CKR_MECHANISM_INVALID;
info = (struct hash_signature_info *) calloc(1, sizeof(*info));
info->mech = mech;
info->sign_type = sign_type;
info->hash_type = hash_type;
info->sign_mech = sign_type->mech;
info->hash_mech = hash_mech;
new_type = sc_pkcs11_new_fw_mechanism(mech, &sign_type->mech_info,
sign_type->key_type, info);
if (new_type)
sc_pkcs11_register_mechanism(p11card, new_type);
return CKR_OK;
}

View File

@ -341,6 +341,9 @@ CK_RV sc_pkcs11_register_generic_mechanisms(struct sc_pkcs11_card *);
#ifdef HAVE_OPENSSL
void sc_pkcs11_register_openssl_mechanisms(struct sc_pkcs11_card *);
#endif
CK_RV sc_pkcs11_register_sign_and_hash_mechanism(struct sc_pkcs11_card *,
CK_MECHANISM_TYPE, CK_MECHANISM_TYPE,
sc_pkcs11_mechanism_type_t *);
#ifdef __cplusplus
}