static KMF_RETURN pk_delete_keys(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attlist, int numattr, char *desc, int *keysdeleted) { KMF_RETURN rv = KMF_OK; uint32_t numkeys = 0; int num = numattr; *keysdeleted = 0; numkeys = 0; kmf_set_attr_at_index(attlist, num, KMF_COUNT_ATTR, &numkeys, sizeof (uint32_t)); num++; rv = kmf_find_key(kmfhandle, num, attlist); if (rv == KMF_OK && numkeys > 0) { KMF_KEY_HANDLE *keys = NULL; char prompt[1024]; (void) snprintf(prompt, sizeof (prompt), gettext("%d %s key(s) found, do you want " "to delete them (y/N) ?"), numkeys, (desc != NULL ? desc : "")); if (!yesno(prompt, gettext("Respond with yes or no.\n"), B_FALSE)) { *keysdeleted = numkeys; return (KMF_OK); } keys = (KMF_KEY_HANDLE *)malloc(numkeys * sizeof (KMF_KEY_HANDLE)); if (keys == NULL) return (KMF_ERR_MEMORY); (void) memset(keys, 0, numkeys * sizeof (KMF_KEY_HANDLE)); kmf_set_attr_at_index(attlist, num, KMF_KEY_HANDLE_ATTR, keys, sizeof (KMF_KEY_HANDLE)); num++; rv = kmf_find_key(kmfhandle, num, attlist); if (rv == KMF_OK) { rv = pk_destroy_keys(kmfhandle, attlist, num); } free(keys); } if (rv == KMF_ERR_KEY_NOT_FOUND) { rv = KMF_OK; } *keysdeleted = numkeys; return (rv); }
static int get_pkcs11_key_value(libzfs_handle_t *hdl, zfs_cmd_t *zc, zfs_crypto_zckey_t cmd, pkcs11_uri_t *p11uri, char **keydata, size_t *keydatalen) { KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; KMF_KEY_CLASS keyclass = KMF_SYMMETRIC; KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY; KMF_ATTRIBUTE attr[10]; KMF_KEY_HANDLE keys; KMF_CREDENTIAL cred; KMF_RAW_SYM_KEY rkey; KMF_HANDLE_T kmfh; KMF_RETURN err; boolean_t true_val = B_TRUE; CK_SLOT_ID slot; CK_TOKEN_INFO info; size_t n = 0; uint32_t numkeys = 0; /* Ask for all of the named keys */ char *token = NULL; if (kmf_initialize(&kmfh, NULL, NULL) != KMF_OK) { errno = EINVAL; return (-1); } kmf_set_attr_at_index(attr, n++, KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype)); if (p11uri->token) { token = strdup((const char *)p11uri->token); } else { /* If the token wasn't set we assume the metaslot */ token = strdup(METASLOT_TOKEN_LABEL); } kmf_set_attr_at_index(attr, n++, KMF_TOKEN_LABEL_ATTR, token, strlen(token)); kmf_set_attr_at_index(attr, n++, KMF_READONLY_ATTR, &true_val, sizeof (true_val)); kmf_set_attr_at_index(attr, n++, KMF_TOKEN_BOOL_ATTR, &true_val, sizeof (true_val)); err = kmf_configure_keystore(kmfh, n, attr); if (err != KMF_OK) goto out; if ((err = kmf_pk11_token_lookup(kmfh, token, &slot)) != KMF_OK || (err = C_GetTokenInfo(slot, &info)) != CKR_OK) goto out; /* Always prompt for PIN since the key is likey CKA_SENSITIVE */ if (prompt_pkcs11_pin(hdl, zc, cmd, p11uri, &cred.cred, &cred.credlen) != 0) goto out; kmf_set_attr_at_index(attr, n++, KMF_CREDENTIAL_ATTR, &cred, sizeof (KMF_CREDENTIAL)); kmf_set_attr_at_index(attr, n++, KMF_KEYLABEL_ATTR, p11uri->object, strlen((const char *)p11uri->object)); kmf_set_attr_at_index(attr, n++, KMF_KEYCLASS_ATTR, &keyclass, sizeof (keyclass)); kmf_set_attr_at_index(attr, n++, KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format)); kmf_set_attr_at_index(attr, n++, KMF_COUNT_ATTR, &numkeys, sizeof (numkeys)); err = kmf_find_key(kmfh, n, attr); if (err != KMF_OK || numkeys != 1) goto out; kmf_set_attr_at_index(attr, n++, KMF_KEY_HANDLE_ATTR, &keys, sizeof (KMF_KEY_HANDLE)); err = kmf_find_key(kmfh, n, attr); err = kmf_get_sym_key_value(kmfh, &keys, &rkey); if (err != KMF_OK) goto out; if (rkey.keydata.len == *keydatalen) { *keydata = zfs_alloc(hdl, rkey.keydata.len); bcopy(rkey.keydata.val, *keydata, rkey.keydata.len); } *keydatalen = rkey.keydata.len; kmf_free_bigint(&rkey.keydata); out: if (token != NULL) free(token); (void) kmf_finalize(kmfh); if (numkeys == 1 && err == KMF_OK) { return (0); } else if (err == KMF_ERR_AUTH_FAILED) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "PKCS#11 token login failed.")); } else if (numkeys == 0) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "PKCS#11 token object not found.")); } else if (numkeys > 1) { zfs_error_aux(hdl, dgettext(TEXT_DOMAIN, "keysource points to multiple PKCS#11" " objects")); } ASSERT(errno != 0); return (-1); }