static CK_RV
gkm_secret_object_get_attribute (GkmObject *base, GkmSession *session, CK_ATTRIBUTE_PTR attr)
{
	GkmSecretObject *self = GKM_SECRET_OBJECT (base);

	switch (attr->type) {
	case CKA_MODIFIABLE:
		return gkm_attribute_set_bool (attr, TRUE);

	case CKA_ID:
		return gkm_attribute_set_string (attr, gkm_secret_object_get_identifier (self));

	case CKA_LABEL:
		return gkm_attribute_set_string (attr, gkm_secret_object_get_label (self));

	case CKA_G_LOCKED:
		return gkm_attribute_set_bool (attr, gkm_secret_object_is_locked (self, session));

	case CKA_G_CREATED:
		return gkm_attribute_set_time (attr, gkm_secret_object_get_created (self));

	case CKA_G_MODIFIED:
		return gkm_attribute_set_time (attr, gkm_secret_object_get_modified (self));
	}

	return GKM_OBJECT_CLASS (gkm_secret_object_parent_class)->get_attribute (base, session, attr);
}
Exemplo n.º 2
0
static gboolean
generate_encrypted_data (EggBuffer *buffer, GkmSecretCollection *collection,
                         GkmSecretData *data)
{
	GkmSecretObject *obj;
	GkmSecretItem *item;
	GList *items, *l;
	GHashTable *attributes;
	const gchar *label;
	GkmSecret *secret;
	GList *acl;
	int i;

	g_assert (buffer);
	g_assert (GKM_IS_SECRET_COLLECTION (collection));
	g_assert (GKM_IS_SECRET_DATA (data));

	/* Make sure we're using non-pageable memory */
	egg_buffer_set_allocator (buffer, egg_secure_realloc);

	items = gkm_secret_collection_get_items (collection);
	for (l = items; l && !egg_buffer_has_error(buffer); l = g_list_next (l)) {
		item = GKM_SECRET_ITEM (l->data);
		obj = GKM_SECRET_OBJECT (l->data);

		label = gkm_secret_object_get_label (obj);
		buffer_add_utf8_string (buffer, label);

		secret = gkm_secret_data_get_secret (data, gkm_secret_object_get_identifier (obj));
		buffer_add_secret (buffer, secret);

		if (!buffer_add_time (buffer, gkm_secret_object_get_created (obj)) ||
		    !buffer_add_time (buffer, gkm_secret_object_get_modified (obj)))
			break;

		/* reserved: */
		if (!buffer_add_utf8_string (buffer, NULL))
			break;
		for (i = 0; i < 4; i++)
			egg_buffer_add_uint32 (buffer, 0);

		attributes = gkm_secret_item_get_fields (item);
		if (!buffer_add_attributes (buffer, attributes, FALSE))
			break;

		acl = g_object_get_data (G_OBJECT (item), "compat-acl");
		if (!generate_acl_data (buffer, acl))
			break;
	}

	g_list_free (items);

	/* Iteration completed prematurely == fail */
	return (l == NULL);
}
static void
gkm_secret_object_get_property (GObject *obj, guint prop_id, GValue *value,
                                    GParamSpec *pspec)
{
	GkmSecretObject *self = GKM_SECRET_OBJECT (obj);

	switch (prop_id) {
	case PROP_LABEL:
		g_value_set_string (value, gkm_secret_object_get_label (self));
		break;
	case PROP_IDENTIFIER:
		g_value_set_string (value, gkm_secret_object_get_identifier (self));
		break;
	case PROP_CREATED:
		g_value_set_long (value, gkm_secret_object_get_created (self));
		break;
	case PROP_MODIFIED:
		g_value_set_long (value, gkm_secret_object_get_modified (self));
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
		break;
	}
}
Exemplo n.º 4
0
GkmDataResult
gkm_secret_binary_write (GkmSecretCollection *collection, GkmSecretData *sdata,
                         gpointer *data, gsize *n_data)
{
	GkmSecretObject *obj;
	EggBuffer to_encrypt;
	GkmSecret *master;
        guchar digest[16];
        EggBuffer buffer;
        gint hash_iterations;
        gint lock_timeout;
        guchar salt[8];
	guint flags = 0;
	int i;

	g_return_val_if_fail (GKM_IS_SECRET_COLLECTION (collection), GKM_DATA_FAILURE);
	g_return_val_if_fail (GKM_IS_SECRET_DATA (sdata), GKM_DATA_LOCKED);
	g_return_val_if_fail (data && n_data, GKM_DATA_FAILURE);
	g_return_val_if_fail (gcry_md_get_algo_dlen (GCRY_MD_MD5) == sizeof (digest), GKM_DATA_FAILURE);

	obj = GKM_SECRET_OBJECT (collection);

	egg_buffer_init_full (&buffer, 256, g_realloc);

	/* Prepare the keyring for encryption */
	hash_iterations = g_random_int_range (1000, 4096);
	gcry_create_nonce (salt, sizeof (salt));

	egg_buffer_append (&buffer, (guchar*)KEYRING_FILE_HEADER, KEYRING_FILE_HEADER_LEN);
	egg_buffer_add_byte (&buffer, 0); /* Major version */
	egg_buffer_add_byte (&buffer, 0); /* Minor version */
	egg_buffer_add_byte (&buffer, 0); /* crypto (0 == AES) */
	egg_buffer_add_byte (&buffer, 0); /* hash (0 == MD5) */

	buffer_add_utf8_string (&buffer, gkm_secret_object_get_label (obj));
	buffer_add_time (&buffer, gkm_secret_object_get_modified (obj));
	buffer_add_time (&buffer, gkm_secret_object_get_created (obj));

	lock_timeout = gkm_secret_collection_get_lock_idle (collection);
	if (lock_timeout) {
		flags |= LOCK_ON_IDLE_FLAG;
	} else {
		lock_timeout = gkm_secret_collection_get_lock_after (collection);
		if (lock_timeout)
			flags |= LOCK_AFTER_FLAG;
	}

	egg_buffer_add_uint32 (&buffer, flags);

	egg_buffer_add_uint32 (&buffer, lock_timeout);
	egg_buffer_add_uint32 (&buffer, hash_iterations);
	egg_buffer_append (&buffer, salt, 8);

	/* Reserved: */
	for (i = 0; i < 4; i++)
		egg_buffer_add_uint32 (&buffer, 0);

	/* Hashed items: */
	generate_hashed_items (collection, &buffer);

	/* Encrypted data. Use non-pageable memory */
	egg_buffer_init_full (&to_encrypt, 4096, egg_secure_realloc);

	egg_buffer_append (&to_encrypt, (guchar*)digest, 16); /* Space for hash */

	if (!generate_encrypted_data (&to_encrypt, collection, sdata)) {
		egg_buffer_uninit (&to_encrypt);
		egg_buffer_uninit (&buffer);
		return GKM_DATA_FAILURE;
	}

	/* Pad with zeros to multiple of 16 bytes */
	while (to_encrypt.len % 16 != 0)
		egg_buffer_add_byte (&to_encrypt, 0);

	gcry_md_hash_buffer (GCRY_MD_MD5, (void*)digest,
			     (guchar*)to_encrypt.buf + 16, to_encrypt.len - 16);
	memcpy (to_encrypt.buf, digest, 16);

	/* If no master password is set, we shouldn't be writing binary... */
	master = gkm_secret_data_get_master (sdata);
	g_return_val_if_fail (master, GKM_DATA_FAILURE);

	if (!encrypt_buffer (&to_encrypt, master, salt, hash_iterations)) {
		egg_buffer_uninit (&buffer);
		egg_buffer_uninit (&to_encrypt);
		return GKM_DATA_FAILURE;
	}

	if (egg_buffer_has_error (&to_encrypt) || egg_buffer_has_error (&buffer)) {
		egg_buffer_uninit (&buffer);
		egg_buffer_uninit (&to_encrypt);
		return GKM_DATA_FAILURE;
	}

	egg_buffer_add_uint32 (&buffer, to_encrypt.len);
	egg_buffer_append (&buffer, to_encrypt.buf, to_encrypt.len);
	egg_buffer_uninit (&to_encrypt);
	*data = egg_buffer_uninit_steal (&buffer, n_data);

	return GKM_DATA_SUCCESS;
}