Blame gcr/gcr-secure-memory.c

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