Blame gcr/gcr-secure-memory.c

Packit b00eeb
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
Packit b00eeb
/* gcr-secure-memory.c - library for allocating memory that is non-pageable
Packit b00eeb
Packit b00eeb
   Copyright (C) 2007 Stefan Walter
Packit b00eeb
   Copyright (C) 2012 Red Hat Inc.
Packit b00eeb
Packit b00eeb
   The Gnome Keyring Library is free software; you can redistribute it and/or
Packit b00eeb
   modify it under the terms of the GNU Library General Public License as
Packit b00eeb
   published by the Free Software Foundation; either version 2 of the
Packit b00eeb
   License, or (at your option) any later version.
Packit b00eeb
Packit b00eeb
   The Gnome Keyring Library is distributed in the hope that it will be useful,
Packit b00eeb
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit b00eeb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit b00eeb
   Library General Public License for more details.
Packit b00eeb
Packit b00eeb
   You should have received a copy of the GNU Library General Public
Packit b00eeb
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
Packit b00eeb
   see <http://www.gnu.org/licenses/>.
Packit b00eeb
Packit b00eeb
   Author: Stef Walter <stefw@gnome.org>
Packit b00eeb
*/
Packit b00eeb
Packit b00eeb
#include "config.h"
Packit b00eeb
Packit b00eeb
#include "gcr-secure-memory.h"
Packit b00eeb
Packit b00eeb
#include "egg/egg-secure-memory.h"
Packit b00eeb
Packit b00eeb
#include <glib.h>
Packit b00eeb
Packit b00eeb
#include <string.h>
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * SECTION:gcr-secure-memory
Packit b00eeb
 * @title: Non-pageable Memory
Packit b00eeb
 * @short_description: Secure non-pageable memory
Packit b00eeb
 *
Packit b00eeb
 * Normal allocated memory can be paged to disk at the whim of the operating
Packit b00eeb
 * system. This can be a problem for sensitive information like passwords, keys
Packit b00eeb
 * and secrets.
Packit b00eeb
 *
Packit b00eeb
 * The Gcr library holds passwords and keys in non-pageable, or locked memory.
Packit b00eeb
 * This is only possible if the OS contains support for it.
Packit b00eeb
 *
Packit b00eeb
 * These functions allow applications to use secure memory to hold passwords
Packit b00eeb
 * and other sensitive information.
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_new: (skip)
Packit b00eeb
 * @type: C type of the objects to allocate
Packit b00eeb
 * @n_objects: number of objects to allocate
Packit b00eeb
 *
Packit b00eeb
 * Allocate objects in non-pageable memory.
Packit b00eeb
 *
Packit b00eeb
 * Returns: (transfer full): the new block of memory
Packit b00eeb
 **/
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_alloc: (skip)
Packit b00eeb
 * @size: The new desired size of the memory block.
Packit b00eeb
 *
Packit b00eeb
 * Allocate a block of non-pageable memory.
Packit b00eeb
 *
Packit b00eeb
 * If non-pageable memory cannot be allocated then normal memory will be
Packit b00eeb
 * returned.
Packit b00eeb
 *
Packit b00eeb
 * Return value: (transfer full): new memory block which should be freed
Packit b00eeb
 * with gcr_secure_memory_free()
Packit b00eeb
 **/
Packit b00eeb
gpointer
Packit b00eeb
gcr_secure_memory_alloc (gsize size)
Packit b00eeb
{
Packit b00eeb
	gpointer memory;
Packit b00eeb
Packit b00eeb
	/* Try to allocate secure memory */
Packit b00eeb
	memory = egg_secure_alloc_full ("gcr-secure-memory", size,
Packit b00eeb
	                                EGG_SECURE_USE_FALLBACK);
Packit b00eeb
Packit b00eeb
	/* Our fallback will always allocate */
Packit b00eeb
	g_assert (memory != NULL);
Packit b00eeb
Packit b00eeb
	return memory;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_try_alloc: (skip)
Packit b00eeb
 * @size: new desired size of the memory block
Packit b00eeb
 *
Packit b00eeb
 * Allocate a block of non-pageable memory.
Packit b00eeb
 *
Packit b00eeb
 * If non-pageable memory cannot be allocated, then %NULL is returned.
Packit b00eeb
 *
Packit b00eeb
 * Return value: (transfer full): new block, or %NULL if memory cannot be
Packit b00eeb
 * allocated; memory block should be freed with gcr_secure_memory_free()
Packit b00eeb
 */
Packit b00eeb
gpointer
Packit b00eeb
gcr_secure_memory_try_alloc (gsize size)
Packit b00eeb
{
Packit b00eeb
	return egg_secure_alloc_full ("gcr-secure-memory", size, 0);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_realloc: (skip)
Packit b00eeb
 * @memory: (allow-none): pointer to reallocate or %NULL to allocate a new block
Packit b00eeb
 * @size: new desired size of the memory block, or 0 to free the memory
Packit b00eeb
 *
Packit b00eeb
 * Reallocate a block of non-pageable memory.
Packit b00eeb
 *
Packit b00eeb
 * Glib memory is also reallocated correctly. If called with a null pointer,
Packit b00eeb
 * then a new block of memory is allocated. If called with a zero size,
Packit b00eeb
 * then the block of memory is freed.
Packit b00eeb
 *
Packit b00eeb
 * If non-pageable memory cannot be allocated then normal memory will be
Packit b00eeb
 * returned.
Packit b00eeb
 *
Packit b00eeb
 * Return value: (transfer full): new block, or %NULL if the block was
Packit b00eeb
 * freed; memory block should be freed with gcr_secure_memory_free()
Packit b00eeb
 */
Packit b00eeb
gpointer
Packit b00eeb
gcr_secure_memory_realloc (gpointer memory,
Packit b00eeb
                           gsize size)
Packit b00eeb
{
Packit b00eeb
	gpointer new_memory;
Packit b00eeb
Packit b00eeb
	if (!memory) {
Packit b00eeb
		return gcr_secure_memory_alloc (size);
Packit b00eeb
	} else if (!size) {
Packit b00eeb
		 gcr_secure_memory_free (memory);
Packit b00eeb
		 return NULL;
Packit b00eeb
	} else if (!egg_secure_check (memory)) {
Packit b00eeb
		return g_realloc (memory, size);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* First try and ask secure memory to reallocate */
Packit b00eeb
	new_memory = egg_secure_realloc_full ("gcr-secure-memory", memory,
Packit b00eeb
	                                      size, EGG_SECURE_USE_FALLBACK);
Packit b00eeb
Packit b00eeb
	g_assert (new_memory != NULL);
Packit b00eeb
Packit b00eeb
	return new_memory;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_try_realloc: (skip)
Packit b00eeb
 * @memory: (allow-none): pointer to reallocate or %NULL to allocate a new block
Packit b00eeb
 * @size: new desired size of the memory block
Packit b00eeb
 *
Packit b00eeb
 * Reallocate a block of non-pageable memory.
Packit b00eeb
 *
Packit b00eeb
 * Glib memory is also reallocated correctly when passed to this function.
Packit b00eeb
 * If called with a null pointer, then a new block of memory is allocated.
Packit b00eeb
 * If called with a zero size, then the block of memory is freed.
Packit b00eeb
 *
Packit b00eeb
 * If memory cannot be allocated, %NULL is returned and the original block
Packit b00eeb
 * of memory remains intact.
Packit b00eeb
 *
Packit b00eeb
 * Return value: (transfer full): the new block, or %NULL if memory cannot be
Packit b00eeb
 * allocated; the memory block should be freed with gcr_secure_memory_free()
Packit b00eeb
 */
Packit b00eeb
gpointer
Packit b00eeb
gcr_secure_memory_try_realloc (gpointer memory,
Packit b00eeb
                               gsize size)
Packit b00eeb
{
Packit b00eeb
	gpointer new_memory;
Packit b00eeb
Packit b00eeb
	if (!memory) {
Packit b00eeb
		return gcr_secure_memory_try_alloc (size);
Packit b00eeb
	} else if (!size) {
Packit b00eeb
		 gcr_secure_memory_free (memory);
Packit b00eeb
		 return NULL;
Packit b00eeb
	} else if (!egg_secure_check (memory)) {
Packit b00eeb
		return g_try_realloc (memory, size);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* First try and ask secure memory to reallocate */
Packit b00eeb
	new_memory = egg_secure_realloc_full ("gcr-secure-memory", memory,
Packit b00eeb
	                                      size, 0);
Packit b00eeb
Packit b00eeb
	/* Might be NULL if reallocation failed. */
Packit b00eeb
	return new_memory;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_free: (skip)
Packit b00eeb
 * @memory: (allow-none): pointer to the beginning of the block of memory to free
Packit b00eeb
 *
Packit b00eeb
 * Free a block of non-pageable memory.
Packit b00eeb
 *
Packit b00eeb
 * Glib memory is also freed correctly when passed to this function. If called
Packit b00eeb
 * with a %NULL pointer then no action is taken.
Packit b00eeb
 */
Packit b00eeb
void
Packit b00eeb
gcr_secure_memory_free (gpointer memory)
Packit b00eeb
{
Packit b00eeb
	if (!memory)
Packit b00eeb
		return;
Packit b00eeb
	egg_secure_free_full (memory, EGG_SECURE_USE_FALLBACK);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_is_secure: (skip)
Packit b00eeb
 * @memory: pointer to check
Packit b00eeb
 *
Packit b00eeb
 * Check if a pointer is in non-pageable memory allocated by.
Packit b00eeb
 *
Packit b00eeb
 * Returns: whether the memory is secure non-pageable memory allocated by the
Packit b00eeb
 *          Gcr library or not
Packit b00eeb
 */
Packit b00eeb
gboolean
Packit b00eeb
gcr_secure_memory_is_secure (gpointer memory)
Packit b00eeb
{
Packit b00eeb
	return egg_secure_check (memory) ? TRUE : FALSE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_strdup: (skip)
Packit b00eeb
 * @string: (allow-none): null terminated string to copy
Packit b00eeb
 *
Packit b00eeb
 * Copy a string into non-pageable memory. If the input string is %NULL, then
Packit b00eeb
 * %NULL will be returned.
Packit b00eeb
 *
Packit b00eeb
 * Returns: copied string, should be freed with gcr_secure_memory_free()
Packit b00eeb
 */
Packit b00eeb
gchar *
Packit b00eeb
gcr_secure_memory_strdup (const gchar* string)
Packit b00eeb
{
Packit b00eeb
	return egg_secure_strdup_full ("gcr-secure-memory", string,
Packit b00eeb
	                               EGG_SECURE_USE_FALLBACK);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
/**
Packit b00eeb
 * gcr_secure_memory_strfree: (skip)
Packit b00eeb
 * @string: (allow-none): null terminated string to fere
Packit b00eeb
 *
Packit b00eeb
 * Free a string, whether securely allocated using these functions or not.
Packit b00eeb
 * This will also clear out the contents of the string so they do not
Packit b00eeb
 * remain in memory.
Packit b00eeb
 */
Packit b00eeb
void
Packit b00eeb
gcr_secure_memory_strfree (gchar *string)
Packit b00eeb
{
Packit b00eeb
	egg_secure_strfree (string);
Packit b00eeb
}