Provide a public PKCS#11 mechanism enumerator
authorMartin Willi <martin@revosec.ch>
Tue, 20 Jul 2010 07:16:05 +0000 (09:16 +0200)
committerMartin Willi <martin@revosec.ch>
Wed, 4 Aug 2010 07:26:21 +0000 (09:26 +0200)
src/libstrongswan/plugins/pkcs11/pkcs11_library.c
src/libstrongswan/plugins/pkcs11/pkcs11_library.h
src/libstrongswan/plugins/pkcs11/pkcs11_manager.c

index d3335dd..9fb1b77 100644 (file)
@@ -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,
index 3cca066..1457d24 100644 (file)
@@ -63,6 +63,18 @@ struct pkcs11_library_t {
                        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.
         */
        void (*destroy)(pkcs11_library_t *this);
index 2428b39..5840600 100644 (file)
@@ -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);
 }
 
 /**