summaryrefslogtreecommitdiff
path: root/gcr/gcr-secure-memory.c
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2012-02-10 17:02:46 +0100
committerStef Walter <stefw@gnome.org>2012-02-10 17:32:35 +0100
commita9e9199acaec4c0af75758cec82bd36612f431ef (patch)
treece062cddf0b2f118fde6c15082917364ec4d897e /gcr/gcr-secure-memory.c
parent347d286e8db2787d26a26ab2336fb9a2884257c9 (diff)
downloadgcr-a9e9199acaec4c0af75758cec82bd36612f431ef.tar.gz
gcr: Expose secure memory API
* Add gcr_secure_memory_new() and gcr_secure_memory_free() and friends. * Exposed so that we can implement secure entry widget in gnome-shell
Diffstat (limited to 'gcr/gcr-secure-memory.c')
-rw-r--r--gcr/gcr-secure-memory.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/gcr/gcr-secure-memory.c b/gcr/gcr-secure-memory.c
new file mode 100644
index 0000000..7a1e99d
--- /dev/null
+++ b/gcr/gcr-secure-memory.c
@@ -0,0 +1,247 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gcr-secure-memory.c - library for allocating memory that is non-pageable
+
+ Copyright (C) 2007 Stefan Walter
+ Copyright (C) 2012 Red Hat Inc.
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw@gnome.org>
+*/
+
+#include "config.h"
+
+#include "gcr-secure-memory.h"
+
+#include "egg/egg-secure-memory.h"
+
+#include <glib.h>
+
+#include <string.h>
+
+/**
+ * SECTION:gcr-secure-memory
+ * @title: Non-pageable Memory
+ * @short_description: Secure non-pageable memory
+ *
+ * Normal allocated memory can be paged to disk at the whim of the operating
+ * system. This can be a problem for sensitive information like passwords, keys
+ * and secrets.
+ *
+ * The Gcr library holds passwords and keys in non-pageable, or locked memory.
+ * This is only possible if the OS contains support for it.
+ *
+ * These functions allow applications to use secure memory to hold passwords
+ * and other sensitive information.
+ */
+
+/**
+ * gcr_secure_memory_new: (skip)
+ * @type: C type of the objects to allocate
+ * @n_objects: number of objects to allocate
+ *
+ * Allocate objects in non-pageable memory.
+ *
+ * Returns: (transfer full): the new block of memory
+ **/
+
+/**
+ * gcr_secure_memory_alloc: (skip)
+ * @size: The new desired size of the memory block.
+ *
+ * Allocate a block of non-pageable memory.
+ *
+ * If non-pageable memory cannot be allocated then normal memory will be
+ * returned.
+ *
+ * Return value: (transfer full): new memory block which should be freed
+ * with gcr_secure_memory_free()
+ **/
+gpointer
+gcr_secure_memory_alloc (gsize size)
+{
+ gpointer memory;
+
+ /* Try to allocate secure memory */
+ memory = egg_secure_alloc_full ("gcr-secure-memory", size,
+ EGG_SECURE_USE_FALLBACK);
+
+ /* Our fallback will always allocate */
+ g_assert (memory != NULL);
+
+ return memory;
+}
+
+/**
+ * gcr_secure_memory_try_alloc: (skip)
+ * @size: new desired size of the memory block
+ *
+ * Allocate a block of non-pageable memory.
+ *
+ * If non-pageable memory cannot be allocated, then %NULL is returned.
+ *
+ * Return value: (transfer full): new block, or %NULL if memory cannot be
+ * allocated; memory block should be freed with gcr_secure_memory_free()
+ */
+gpointer
+gcr_secure_memory_try_alloc (gsize size)
+{
+ return egg_secure_alloc_full ("gcr-secure-memory", size, 0);
+}
+
+/**
+ * gcr_secure_memory_realloc: (skip)
+ * @memory: (allow-none): pointer to reallocate or %NULL to allocate a new block
+ * @size: new desired size of the memory block, or 0 to free the memory
+ *
+ * Reallocate a block of non-pageable memory.
+ *
+ * Glib memory is also reallocated correctly. If called with a null pointer,
+ * then a new block of memory is allocated. If called with a zero size,
+ * then the block of memory is freed.
+ *
+ * If non-pageable memory cannot be allocated then normal memory will be
+ * returned.
+ *
+ * Return value: (transfer full): new block, or %NULL if the block was
+ * freed; memory block should be freed with gcr_secure_memory_free()
+ */
+gpointer
+gcr_secure_memory_realloc (gpointer memory,
+ gsize size)
+{
+ gpointer new_memory;
+
+ if (!memory) {
+ return gcr_secure_memory_alloc (size);
+ } else if (!size) {
+ gcr_secure_memory_free (memory);
+ return NULL;
+ } else if (!egg_secure_check (memory)) {
+ return g_realloc (memory, size);
+ }
+
+ /* First try and ask secure memory to reallocate */
+ new_memory = egg_secure_realloc_full ("gcr-secure-memory", memory,
+ size, EGG_SECURE_USE_FALLBACK);
+
+ g_assert (new_memory != NULL);
+
+ return new_memory;
+}
+
+/**
+ * gcr_secure_memory_try_realloc: (skip)
+ * @memory: (allow-none): pointer to reallocate or %NULL to allocate a new block
+ * @size: new desired size of the memory block
+ *
+ * Reallocate a block of non-pageable memory.
+ *
+ * Glib memory is also reallocated correctly when passed to this function.
+ * If called with a null pointer, then a new block of memory is allocated.
+ * If called with a zero size, then the block of memory is freed.
+ *
+ * If memory cannot be allocated, %NULL is returned and the original block
+ * of memory remains intact.
+ *
+ * Return value: (transfer full): the new block, or %NULL if memory cannot be
+ * allocated; the memory block should be freed with gcr_secure_memory_free()
+ */
+gpointer
+gcr_secure_memory_try_realloc (gpointer memory,
+ gsize size)
+{
+ gpointer new_memory;
+
+ if (!memory) {
+ return gcr_secure_memory_try_alloc (size);
+ } else if (!size) {
+ gcr_secure_memory_free (memory);
+ return NULL;
+ } else if (!egg_secure_check (memory)) {
+ return g_try_realloc (memory, size);
+ }
+
+ /* First try and ask secure memory to reallocate */
+ new_memory = egg_secure_realloc_full ("gcr-secure-memory", memory,
+ size, 0);
+
+ g_assert (new_memory != NULL);
+
+ return new_memory;
+}
+
+/**
+ * gcr_secure_memory_free: (skip)
+ * @memory: (allow-none): pointer to the beginning of the block of memory to free
+ *
+ * Free a block of non-pageable memory.
+ *
+ * Glib memory is also freed correctly when passed to this function. If called
+ * with a %NULL pointer then no action is taken.
+ */
+void
+gcr_secure_memory_free (gpointer memory)
+{
+ if (!memory)
+ return;
+ egg_secure_free_full (memory, EGG_SECURE_USE_FALLBACK);
+}
+
+/**
+ * gcr_secure_memory_is_secure: (skip)
+ * @memory: pointer to check
+ *
+ * Check if a pointer is in non-pageable memory allocated by.
+ *
+ * Returns: whether the memory is secure non-pageable memory allocated by the
+ * Gcr library or not
+ */
+gboolean
+gcr_secure_memory_is_secure (gpointer memory)
+{
+ return egg_secure_check (memory) ? TRUE : FALSE;
+}
+
+/**
+ * gcr_secure_memory_strdup: (skip)
+ * @string: (allow-none): null terminated string to copy
+ *
+ * Copy a string into non-pageable memory. If the input string is %NULL, then
+ * %NULL will be returned.
+ *
+ * Returns: copied string, should be freed with gcr_secure_memory_free()
+ */
+gchar *
+gcr_secure_memory_strdup (const gchar* string)
+{
+ return egg_secure_strdup_full ("gcr-secure-memory", string,
+ EGG_SECURE_USE_FALLBACK);
+}
+
+/**
+ * gcr_secure_memory_strfree: (skip)
+ * @string: (allow-none): null terminated string to fere
+ *
+ * Free a string, whether securely allocated using these functions or not.
+ * This will also clear out the contents of the string so they do not
+ * remain in memory.
+ */
+void
+gcr_secure_memory_strfree (gchar *string)
+{
+ egg_secure_strfree (string);
+}