Implemented keyid discovery on all modules/slots
This commit is contained in:
@@ -217,6 +217,66 @@ static pkcs11_library_t* find_lib(char *module)
|
|||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the PKCS#11 lib having a keyid, and optionally a slot
|
||||||
|
*/
|
||||||
|
static pkcs11_library_t* find_lib_by_keyid(chunk_t keyid, int *slot)
|
||||||
|
{
|
||||||
|
pkcs11_manager_t *manager;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
pkcs11_library_t *p11, *found = NULL;
|
||||||
|
CK_SLOT_ID current;
|
||||||
|
|
||||||
|
manager = pkcs11_manager_get();
|
||||||
|
if (!manager)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
enumerator = manager->create_token_enumerator(manager);
|
||||||
|
while (enumerator->enumerate(enumerator, &p11, ¤t))
|
||||||
|
{
|
||||||
|
if (*slot == -1 || *slot == current)
|
||||||
|
{
|
||||||
|
/* we look for a public key, it is usually readable without login */
|
||||||
|
CK_OBJECT_CLASS class = CKO_PUBLIC_KEY;
|
||||||
|
CK_ATTRIBUTE tmpl[] = {
|
||||||
|
{CKA_CLASS, &class, sizeof(class)},
|
||||||
|
{CKA_ID, keyid.ptr, keyid.len},
|
||||||
|
};
|
||||||
|
CK_OBJECT_HANDLE object;
|
||||||
|
CK_SESSION_HANDLE session;
|
||||||
|
CK_RV rv;
|
||||||
|
enumerator_t *keys;
|
||||||
|
|
||||||
|
rv = p11->f->C_OpenSession(current, CKF_SERIAL_SESSION, NULL, NULL,
|
||||||
|
&session);
|
||||||
|
if (rv != CKR_OK)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "opening PKCS#11 session failed: %N",
|
||||||
|
ck_rv_names, rv);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
keys = p11->create_object_enumerator(p11, session,
|
||||||
|
tmpl, countof(tmpl), NULL, 0);
|
||||||
|
if (keys->enumerate(keys, &object))
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "found key on PKCS#11 token '%s':%d",
|
||||||
|
p11->get_name(p11), current);
|
||||||
|
found = p11;
|
||||||
|
*slot = current;
|
||||||
|
}
|
||||||
|
keys->destroy(keys);
|
||||||
|
p11->f->C_CloseSession(session);
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the key on the token
|
* Find the key on the token
|
||||||
*/
|
*/
|
||||||
@@ -305,8 +365,8 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!keyid.len || !pin.len || !module || slot == -1)
|
if (!keyid.len || !pin.len)
|
||||||
{ /* we currently require all parameters, TODO: search for pubkeys */
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,12 +388,25 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args)
|
|||||||
.ref = 1,
|
.ref = 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
this->lib = find_lib(module);
|
if (module && slot != -1)
|
||||||
if (!this->lib)
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "PKCS#11 module '%s' not found", module);
|
this->lib = find_lib(module);
|
||||||
free(this);
|
if (!this->lib)
|
||||||
return NULL;
|
{
|
||||||
|
DBG1(DBG_CFG, "PKCS#11 module '%s' not found", module);
|
||||||
|
free(this);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->lib = find_lib_by_keyid(keyid, &slot);
|
||||||
|
if (!this->lib)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "no PKCS#11 module found having a keyid %#B", &keyid);
|
||||||
|
free(this);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rv = this->lib->f->C_OpenSession(slot, CKF_SERIAL_SESSION,
|
rv = this->lib->f->C_OpenSession(slot, CKF_SERIAL_SESSION,
|
||||||
|
|||||||
Reference in New Issue
Block a user