mem_cred_t *creds;
/**
+ * separate credential set for token PINs
+ */
+ mem_cred_t *pins;
+
+ /**
* cache CRLs to disk?
*/
bool cachecrl;
private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
{
chunk_t keyid;
- char *hex, *msg = NULL;
+ char buf[BUF_LEN], *hex, *msg = NULL;
hex = message->get_str(message, NULL, "id");
if (!hex)
return create_reply("key id missing");
}
keyid = chunk_from_hex(chunk_from_str(hex), NULL);
- DBG1(DBG_CFG, "unloaded private key with id %+B", &keyid);
- if (!this->creds->remove_key(this->creds, keyid))
+ snprintf(buf, sizeof(buf), "%+B", &keyid);
+ DBG1(DBG_CFG, "unloaded private key with id %s", buf);
+ if (this->creds->remove_key(this->creds, keyid))
+ { /* also remove any potential PIN associated with this id */
+ this->pins->remove_shared_unique(this->pins, buf);
+ }
+ else
{
msg = "key not found";
}
return builder->finalize(builder);
}
+CALLBACK(load_token, vici_message_t*,
+ private_vici_cred_t *this, char *name, u_int id, vici_message_t *message)
+{
+ vici_builder_t *builder;
+ private_key_t *key;
+ shared_key_t *shared = NULL;
+ identification_t *owner;
+ mem_cred_t *set = NULL;
+ chunk_t handle, fp;
+ char buf[BUF_LEN], *hex, *module, *pin, *unique = NULL;
+ int slot;
+
+ hex = message->get_str(message, NULL, "handle");
+ if (!hex)
+ {
+ return create_reply("keyid missing");
+ }
+ handle = chunk_from_hex(chunk_from_str(hex), NULL);
+ slot = message->get_int(message, -1, "slot");
+ module = message->get_str(message, NULL, "module");
+ pin = message->get_str(message, NULL, "pin");
+
+ if (pin)
+ { /* provide the pin in a temporary credential set to access the key */
+ shared = shared_key_create(SHARED_PIN, chunk_clone(chunk_from_str(pin)));
+ owner = identification_create_from_encoding(ID_KEY_ID, handle);
+ set = mem_cred_create();
+ set->add_shared(set, shared->get_ref(shared), owner, NULL);
+ lib->credmgr->add_local_set(lib->credmgr, &set->set, FALSE);
+ }
+ if (slot >= 0)
+ {
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
+ BUILD_PKCS11_KEYID, handle,
+ BUILD_PKCS11_SLOT, slot,
+ module ? BUILD_PKCS11_MODULE : BUILD_END, module,
+ BUILD_END);
+ }
+ else
+ {
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_ANY,
+ BUILD_PKCS11_KEYID, handle,
+ module ? BUILD_PKCS11_MODULE : BUILD_END, module,
+ BUILD_END);
+ }
+ if (set)
+ {
+ lib->credmgr->remove_local_set(lib->credmgr, &set->set);
+ set->destroy(set);
+ }
+ if (!key)
+ {
+ chunk_free(&handle);
+ DESTROY_IF(shared);
+ return create_reply("loading private key from token failed");
+ }
+ builder = vici_builder_create();
+ builder->add_kv(builder, "success", "yes");
+ if (key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &fp))
+ {
+ snprintf(buf, sizeof(buf), "%+B", &fp);
+ builder->add_kv(builder, "id", "%s", buf);
+ unique = buf;
+ }
+ if (shared && unique)
+ { /* use the handle as owner, but the key identifier as unique ID */
+ owner = identification_create_from_encoding(ID_KEY_ID, handle);
+ this->pins->add_shared_unique(this->pins, unique, shared,
+ linked_list_create_with_items(owner, NULL));
+ }
+ else
+ {
+ DESTROY_IF(shared);
+ }
+ DBG1(DBG_CFG, "loaded %N private key from token", key_type_names,
+ key->get_type(key));
+ this->creds->add_key(this->creds, key);
+ chunk_free(&handle);
+ return builder->finalize(builder);
+}
+
CALLBACK(shared_owners, bool,
linked_list_t *owners, vici_message_t *message, char *name, chunk_t value)
{
manage_command(this, "load-key", load_key, reg);
manage_command(this, "unload-key", unload_key, reg);
manage_command(this, "get-keys", get_keys, reg);
+ manage_command(this, "load-token", load_token, reg);
manage_command(this, "load-shared", load_shared, reg);
manage_command(this, "unload-shared", unload_shared, reg);
manage_command(this, "get-shared", get_shared, reg);
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
this->creds->destroy(this->creds);
+ lib->credmgr->remove_set(lib->credmgr, &this->pins->set);
+ this->pins->destroy(this->pins);
free(this);
}
},
.dispatcher = dispatcher,
.creds = mem_cred_create(),
+ .pins = mem_cred_create(),
);
if (lib->settings->get_bool(lib->settings, "%s.cache_crls", FALSE, lib->ns))
DBG1(DBG_CFG, "crl caching to %s enabled", CRL_DIR);
}
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
+ lib->credmgr->add_set(lib->credmgr, &this->pins->set);
manage_commands(this, TRUE);