int LUKS2_keyslots_validate(struct crypt_device *cd, json_object *hdr_jobj)
{
	const keyslot_handler *h;
	int keyslot;
	json_object *jobj_keyslots, *jobj_type;

	if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
		return -EINVAL;

	json_object_object_foreach(jobj_keyslots, slot, val) {
		keyslot = atoi(slot);
		json_object_object_get_ex(val, "type", &jobj_type);
		h = LUKS2_keyslot_handler_type(cd, json_object_get_string(jobj_type));
		if (!h)
			continue;
		if (h->validate && h->validate(cd, val)) {
			log_dbg(cd, "Keyslot type %s validation failed on keyslot %d.", h->name, keyslot);
			return -EINVAL;
		}

		if (!strcmp(h->name, "luks2") && LUKS2_get_keyslot_digests_count(hdr_jobj, keyslot) != 1) {
			log_dbg(cd, "Keyslot %d is not assigned to exactly 1 digest.", keyslot);
			return -EINVAL;
		}
	}

	return 0;
}
int LUKS2_keyslots_validate(struct crypt_device *cd, json_object *hdr_jobj)
{
	const keyslot_handler *h;
	int keyslot;
	json_object *jobj_keyslots, *jobj_type;

	if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
		return -EINVAL;

	json_object_object_foreach(jobj_keyslots, slot, val) {
		keyslot = atoi(slot);
		json_object_object_get_ex(val, "type", &jobj_type);
		h = LUKS2_keyslot_handler_type(cd, json_object_get_string(jobj_type));
		if (!h)
			continue;
		if (h->validate && h->validate(cd, val)) {
			log_dbg(cd, "Keyslot type %s validation failed on keyslot %d.", h->name, keyslot);
			return -EINVAL;
		}

		if (!strcmp(h->name, "luks2") && LUKS2_get_keyslot_digests_count(hdr_jobj, keyslot) != 1) {
			log_dbg(cd, "Keyslot %d is not assigned to exactly 1 digest.", keyslot);
			return -EINVAL;
		}
	}

	return 0;
}