From: Martin Willi Date: Tue, 20 Jul 2010 07:16:05 +0000 (+0200) Subject: Provide a public PKCS#11 mechanism enumerator X-Git-Tag: 4.5.0~588 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5a27bf8ad807ee0e764347e25712e0c95952a510;p=thirdparty%2Fstrongswan.git Provide a public PKCS#11 mechanism enumerator --- diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c index d3335dd210..9fb1b77696 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.c @@ -613,6 +613,89 @@ METHOD(pkcs11_library_t, create_object_enumerator, enumerator_t*, return &enumerator->public; } +/** + * Enumerator over mechanisms + */ +typedef struct { + /* implements enumerator_t */ + enumerator_t public; + /* PKCS#11 library */ + pkcs11_library_t *lib; + /* slot of token */ + CK_SLOT_ID slot; + /* mechanism type list */ + CK_MECHANISM_TYPE_PTR mechs; + /* number of mechanism types */ + CK_ULONG count; + /* current mechanism */ + CK_ULONG current; +} mechanism_enumerator_t; + +METHOD(enumerator_t, enumerate_mech, bool, + mechanism_enumerator_t *this, CK_MECHANISM_TYPE* type, + CK_MECHANISM_INFO *info) +{ + CK_RV rv; + + if (this->current >= this->count) + { + return FALSE; + } + if (info) + { + rv = this->lib->f->C_GetMechanismInfo(this->slot, + this->mechs[this->current], info); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GetMechanismInfo() failed: %N", ck_rv_names, rv); + return FALSE; + } + } + *type = this->mechs[this->current++]; + return TRUE; +} + +METHOD(enumerator_t, destroy_mech, void, + mechanism_enumerator_t *this) +{ + free(this->mechs); + free(this); +} + +METHOD(pkcs11_library_t, create_mechanism_enumerator, enumerator_t*, + private_pkcs11_library_t *this, CK_SLOT_ID slot) +{ + mechanism_enumerator_t *enumerator; + CK_RV rv; + + INIT(enumerator, + .public = { + .enumerate = (void*)_enumerate_mech, + .destroy = _destroy_mech, + }, + .lib = &this->public, + .slot = slot, + ); + + rv = enumerator->lib->f->C_GetMechanismList(slot, NULL, &enumerator->count); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv); + free(enumerator); + return enumerator_create_empty(); + } + enumerator->mechs = malloc(sizeof(CK_MECHANISM_TYPE) * enumerator->count); + enumerator->lib->f->C_GetMechanismList(slot, enumerator->mechs, + &enumerator->count); + if (rv != CKR_OK) + { + DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv); + destroy_mech(enumerator); + return enumerator_create_empty(); + } + return &enumerator->public; +} + METHOD(pkcs11_library_t, destroy, void, private_pkcs11_library_t *this) { @@ -761,6 +844,7 @@ pkcs11_library_t *pkcs11_library_create(char *name, char *file) .public = { .get_name = _get_name, .create_object_enumerator = _create_object_enumerator, + .create_mechanism_enumerator = _create_mechanism_enumerator, .destroy = _destroy, }, .name = name, diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h index 3cca066787..1457d24d4c 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_library.h +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_library.h @@ -62,6 +62,18 @@ struct pkcs11_library_t { CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR tmpl, CK_ULONG tcount, CK_ATTRIBUTE_PTR attr, CK_ULONG acount); + /** + * Create an enumerator over supported mechanisms of a token. + * + * The resulting enumerator enumerates over the mechanism type, and if + * a non-NULL pointer is given, over the mechanism info details. + * + * @param slot slot of the token + * @return enumerator over (CK_MECHANISM_TYPE, CK_MECHANISM_INFO) + */ + enumerator_t* (*create_mechanism_enumerator)(pkcs11_library_t *this, + CK_SLOT_ID slot); + /** * Destroy a pkcs11_library_t. */ diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c index 2428b39ded..58406008d6 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_manager.c @@ -84,54 +84,31 @@ static void lib_entry_destroy(lib_entry_t *entry) */ static void print_mechs(lib_entry_t *entry, CK_SLOT_ID slot) { - CK_MECHANISM_TYPE_PTR mechs; + enumerator_t *enumerator; + CK_MECHANISM_TYPE type; CK_MECHANISM_INFO info; - CK_ULONG count; - CK_RV rv; - int i; - rv = entry->lib->f->C_GetMechanismList(slot, NULL, &count); - if (rv != CKR_OK) + enumerator = entry->lib->create_mechanism_enumerator(entry->lib, slot); + while (enumerator->enumerate(enumerator, &type, &info)) { - DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv); - return; + DBG2(DBG_CFG, " %N %lu-%lu [ %s%s%s%s%s%s%s%s%s%s%s%s%s]", + ck_mech_names, type, + info.ulMinKeySize, info.ulMaxKeySize, + info.flags & CKF_HW ? "HW " : "", + info.flags & CKF_ENCRYPT ? "ENCR " : "", + info.flags & CKF_DECRYPT ? "DECR " : "", + info.flags & CKF_DIGEST ? "DGST " : "", + info.flags & CKF_SIGN ? "SIGN " : "", + info.flags & CKF_SIGN_RECOVER ? "SIGN_RCVR " : "", + info.flags & CKF_VERIFY ? "VRFY " : "", + info.flags & CKF_VERIFY_RECOVER ? "VRFY_RCVR " : "", + info.flags & CKF_GENERATE ? "GEN " : "", + info.flags & CKF_GENERATE_KEY_PAIR ? "GEN_KEY_PAIR " : "", + info.flags & CKF_WRAP ? "WRAP " : "", + info.flags & CKF_UNWRAP ? "UNWRAP " : "", + info.flags & CKF_DERIVE ? "DERIVE " : ""); } - mechs = malloc(sizeof(CK_MECHANISM_TYPE) * count); - entry->lib->f->C_GetMechanismList(slot, mechs, &count); - if (rv != CKR_OK) - { - DBG1(DBG_CFG, "C_GetMechanismList() failed: %N", ck_rv_names, rv); - return; - } - for (i = 0; i < count; i++) - { - rv = entry->lib->f->C_GetMechanismInfo(slot, mechs[i], &info); - if (rv == CKR_OK) - { - DBG2(DBG_CFG, " %N %lu-%lu [ %s%s%s%s%s%s%s%s%s%s%s%s%s]", - ck_mech_names, mechs[i], - info.ulMinKeySize, info.ulMaxKeySize, - info.flags & CKF_HW ? "HW " : "", - info.flags & CKF_ENCRYPT ? "ENCR " : "", - info.flags & CKF_DECRYPT ? "DECR " : "", - info.flags & CKF_DIGEST ? "DGST " : "", - info.flags & CKF_SIGN ? "SIGN " : "", - info.flags & CKF_SIGN_RECOVER ? "SIGN_RCVR " : "", - info.flags & CKF_VERIFY ? "VRFY " : "", - info.flags & CKF_VERIFY_RECOVER ? "VRFY_RCVR " : "", - info.flags & CKF_GENERATE ? "GEN " : "", - info.flags & CKF_GENERATE_KEY_PAIR ? "GEN_KEY_PAIR " : "", - info.flags & CKF_WRAP ? "WRAP " : "", - info.flags & CKF_UNWRAP ? "UNWRAP " : "", - info.flags & CKF_DERIVE ? "DERIVE " : ""); - } - else - { - DBG1(DBG_CFG, "C_GetMechanismList(%N) failed: %N", - ck_mech_names, mechs[i], ck_rv_names, rv); - } - } - free(mechs); + enumerator->destroy(enumerator); } /**