From: Martin Willi Date: Fri, 16 Jul 2010 09:17:06 +0000 (+0200) Subject: Implemented keyid discovery on all modules/slots X-Git-Tag: 4.5.0~605 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7afc00d03cdfeef0185ef1a7d058c0e99b4789d2;p=thirdparty%2Fstrongswan.git Implemented keyid discovery on all modules/slots --- diff --git a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c index 0084fb4009..c6b8645e6b 100644 --- a/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c +++ b/src/libstrongswan/plugins/pkcs11/pkcs11_private_key.c @@ -217,6 +217,66 @@ static pkcs11_library_t* find_lib(char *module) 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 */ @@ -305,8 +365,8 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args) } break; } - if (!keyid.len || !pin.len || !module || slot == -1) - { /* we currently require all parameters, TODO: search for pubkeys */ + if (!keyid.len || !pin.len) + { return NULL; } @@ -328,12 +388,25 @@ pkcs11_private_key_t *pkcs11_private_key_connect(key_type_t type, va_list args) .ref = 1, ); - this->lib = find_lib(module); - if (!this->lib) + if (module && slot != -1) { - DBG1(DBG_CFG, "PKCS#11 module '%s' not found", module); - free(this); - return NULL; + this->lib = find_lib(module); + if (!this->lib) + { + 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,