gnome-keyring r1463 - in trunk: . egg egg/tests gcr gcr/template gcr/tests gcr/tests/test-data gp11 pkcs11/gck pkcs11/gck/tests pkcs11/roots-store pkcs11/ssh-store pkcs11/user-store



Author: nnielsen
Date: Sun Jan 18 22:24:09 2009
New Revision: 1463
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1463&view=rev

Log:
	* egg/egg-asn1.c:
	* egg/egg-hex.c: (split from pkcs11/gck/gck-util.c)
	* egg/egg-hex.h: (split from pkcs11/gck/gck-util.h)
	* egg/egg-openssl.c: (moved from pkcs11/gck/gck-data-openssl.c)
	* egg/egg-openssl.h: (moved from pkcs11/gck/gck-data-openssl.h)
	* egg/egg-symkey.c: (split from pkcs11/gck/gck-crypto.c)
	* egg/egg-symkey.h: (split from pkcs11/gck/gck-crypto.h)
	* egg/Makefile.am:
	* egg/tests/Makefile.am:
	* egg/tests/unit-test-asn1.c:
	* egg/tests/unit-test-hex.c: (moved from pkcs11/gck/tests/unit-test-util.c)
	* egg/tests/unit-test-openssl.c: (moved from pkcs11/gck/tests/unit-test-data-openssl.c)
	* egg/tests/unit-test-symkey.c: (split from pkcs11/gck/tests/unit-test-crypto.c)
	* gcr/gcr.pc.in: (added)
	* gcr/gcr-internal.c: (added)
	* gcr/gcr-internal.h: (added)
	* gcr/gcr-marshal.list: (added)
	* gcr/gcr-parser.c: (added)
	* gcr/gcr-parser.h: (added)
	* gcr/gcr-types.h: (added)
	* gcr/Makefile.am: (added)
	* gcr/template/*: (added)
	* gcr/tests/Makefile.am: (added)
	* gcr/tests/unit-test-parser.c: (added)
	* gcr/tests/test-data: (copied from daemon/pkix/test/test-data)
	* gp11/gp11.h:
	* pkcs11/gck/gck-crypto.c:
	* pkcs11/gck/gck-crypto.h:
	* pkcs11/gck/gck-data-der.c:
	* pkcs11/gck/gck-data-der.h:
	* pkcs11/gck/gck-data-file.c:
	* pkcs11/gck/gck-data-openssl.c: (moved)
	* pkcs11/gck/gck-data-openssl.h: (moved)
	* pkcs11/gck/gck-data-pem.c: (combined into egg/egg-openssl.c)
	* pkcs11/gck/gck-data-pem.c: (combined into egg/egg-openssl.h)
	* pkcs11/gck/gck-util.c:
	* pkcs11/gck/gck-util.h:
	* pkcs11/gck/Makefile.am:
	* pkcs11/gck/tests/unit-test-crypto.c:
	* pkcs11/gck/tests/unit-test-data-openssl.c: (moved)
	* pkcs11/gck/tests/unit-test-util.c: (moved)
	* pkcs11/roots-store/gck-roots-module.c:
	* pkcs11/ssh-store/gck-ssh-openssh.c:
	* pkcs11/user-store/gck-user-storage.c:
	* configure.in:
	* Makefile.am: Add new gcr library for crypto UI and related tasks. Implement
	GckParser class.


Added:
   trunk/egg/egg-hex.c   (contents, props changed)
      - copied, changed from r1460, /trunk/pkcs11/gck/gck-util.c
   trunk/egg/egg-hex.h   (contents, props changed)
      - copied, changed from r1460, /trunk/pkcs11/gck/gck-util.h
   trunk/egg/egg-openssl.c   (contents, props changed)
      - copied, changed from r1460, /trunk/pkcs11/gck/gck-data-openssl.c
   trunk/egg/egg-openssl.h   (contents, props changed)
      - copied, changed from r1460, /trunk/pkcs11/gck/gck-data-openssl.h
   trunk/egg/egg-symkey.c   (contents, props changed)
      - copied, changed from r1461, /trunk/pkcs11/gck/gck-crypto.c
   trunk/egg/egg-symkey.h   (contents, props changed)
      - copied, changed from r1460, /trunk/pkcs11/gck/gck-crypto.h
   trunk/egg/tests/unit-test-hex.c   (contents, props changed)
      - copied, changed from r1460, /trunk/pkcs11/gck/tests/unit-test-util.c
   trunk/egg/tests/unit-test-openssl.c   (contents, props changed)
      - copied, changed from r1460, /trunk/pkcs11/gck/tests/unit-test-data-openssl.c
   trunk/egg/tests/unit-test-symkey.c   (contents, props changed)
      - copied, changed from r1460, /trunk/pkcs11/gck/tests/unit-test-crypto.c
   trunk/gcr/   (props changed)
   trunk/gcr/Makefile.am
   trunk/gcr/gcr-import-dialog.glade
   trunk/gcr/gcr-importer.c
   trunk/gcr/gcr-importer.h
   trunk/gcr/gcr-internal.c
   trunk/gcr/gcr-internal.h
   trunk/gcr/gcr-marshal.list
   trunk/gcr/gcr-parser.c
   trunk/gcr/gcr-parser.h
   trunk/gcr/gcr-types.h
   trunk/gcr/gcr.pc.in
   trunk/gcr/template/
   trunk/gcr/template/gcr-xxx.c
   trunk/gcr/template/gcr-xxx.h
   trunk/gcr/tests/   (props changed)
   trunk/gcr/tests/Makefile.am
   trunk/gcr/tests/test-data/   (props changed)
      - copied from r1460, /trunk/daemon/pkix/tests/test-data/
   trunk/gcr/tests/unit-test-parser.c   (contents, props changed)
      - copied, changed from r1461, /trunk/daemon/pkix/tests/unit-test-pkix-parser.c
Removed:
   trunk/pkcs11/gck/gck-data-openssl.c
   trunk/pkcs11/gck/gck-data-openssl.h
   trunk/pkcs11/gck/gck-data-pem.c
   trunk/pkcs11/gck/gck-data-pem.h
   trunk/pkcs11/gck/tests/unit-test-data-openssl.c
   trunk/pkcs11/gck/tests/unit-test-util.c
Modified:
   trunk/ChangeLog
   trunk/Makefile.am
   trunk/configure.in
   trunk/egg/Makefile.am
   trunk/egg/egg-asn1.c
   trunk/egg/tests/Makefile.am
   trunk/egg/tests/unit-test-asn1.c
   trunk/gp11/gp11.h
   trunk/pkcs11/gck/Makefile.am
   trunk/pkcs11/gck/gck-crypto.c
   trunk/pkcs11/gck/gck-crypto.h
   trunk/pkcs11/gck/gck-data-der.c
   trunk/pkcs11/gck/gck-data-der.h
   trunk/pkcs11/gck/gck-data-file.c
   trunk/pkcs11/gck/gck-util.c
   trunk/pkcs11/gck/gck-util.h
   trunk/pkcs11/gck/tests/Makefile.am
   trunk/pkcs11/gck/tests/unit-test-crypto.c
   trunk/pkcs11/roots-store/gck-roots-module.c
   trunk/pkcs11/ssh-store/gck-ssh-openssh.c
   trunk/pkcs11/user-store/gck-user-storage.c

Modified: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am	(original)
+++ trunk/Makefile.am	Sun Jan 18 22:24:09 2009
@@ -14,6 +14,7 @@
 	. \
 	gp11 \
 	egg \
+	gcr \
 	common \
 	library \
 	pkcs11 \

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Sun Jan 18 22:24:09 2009
@@ -4,12 +4,16 @@
 AM_CONFIG_HEADER(config.h)
 	
 dnl ****************************************************************************
-dnl GP11 library libtool versioning
+dnl Library libtool versioning
 
 GP11_MAJOR=0		# Increment for major version number, breaks old apps.
 GP11_REVISION=0		# Increment for internal changes, nothing affected.
 GP11_AGE=0		# Increment for interface that doesn't break anything
 
+GCR_MAJOR=0		# Increment for major version number, breaks old apps.
+GCR_REVISION=0		# Increment for internal changes, nothing affected.
+GCR_AGE=0		# Increment for interface that doesn't break anything
+
 dnl ****************************************************************************
 
 AM_SANITY_CHECK
@@ -469,6 +473,10 @@
 AC_SUBST(GP11_LT_RELEASE)
 AC_SUBST(GP11_MAJOR)
 
+GCR_LT_RELEASE=$GCR_MAJOR:$GCR_REVISION:$GCR_AGE
+AC_SUBST(GCR_LT_RELEASE)
+AC_SUBST(GCR_MAJOR)
+
 AC_SUBST(DAEMON_CFLAGS)
 AC_SUBST(DAEMON_LIBS)
 
@@ -497,6 +505,9 @@
 daemon/ui/Makefile
 egg/Makefile
 egg/tests/Makefile
+gcr/gcr.pc
+gcr/Makefile
+gcr/tests/Makefile
 gp11/gp11.pc
 gp11/Makefile
 gp11/reference/Makefile

Modified: trunk/egg/Makefile.am
==============================================================================
--- trunk/egg/Makefile.am	(original)
+++ trunk/egg/Makefile.am	Sun Jan 18 22:24:09 2009
@@ -19,8 +19,11 @@
 libegg_la_SOURCES = \
 	egg-asn1.c egg-asn1.h \
 	egg-buffer.c egg-buffer.h \
+	egg-hex.c egg-hex.h \
+	egg-openssl.c egg-openssl.h \
 	egg-unix-credentials.c egg-unix-credentials.h \
-	egg-secure-memory.c egg-secure-memory.h
+	egg-secure-memory.c egg-secure-memory.h \
+	egg-symkey.c egg-symkey.h
 	
 asn1-def-pk.h: pk.asn
 	asn1Parser -o asn1-def-pk.h pk.asn 

Modified: trunk/egg/egg-asn1.c
==============================================================================
--- trunk/egg/egg-asn1.c	(original)
+++ trunk/egg/egg-asn1.c	Sun Jan 18 22:24:09 2009
@@ -335,12 +335,9 @@
 	if (!buf)
 		return 0;
 		
-	quark = g_quark_try_string ((gchar*)buf);
+	quark = g_quark_from_string ((gchar*)buf);
 	g_free (buf);
 	
-	if (quark == 0)
-		quark = g_quark_from_static_string ("0.UNKNOWN.OID");
-	
 	return quark;
 }
 

Copied: trunk/egg/egg-hex.c (from r1460, /trunk/pkcs11/gck/gck-util.c)
==============================================================================
--- /trunk/pkcs11/gck/gck-util.c	(original)
+++ trunk/egg/egg-hex.c	Sun Jan 18 22:24:09 2009
@@ -21,77 +21,14 @@
 
 #include "config.h"
 
-#include "gck-util.h"
+#include "egg-hex.h"
 
-#include <stdio.h>
 #include <string.h>
 
-/* Only access using atomic operations */
-static gint next_handle = 0x00000010;
-
 static const char HEXC[] = "0123456789ABCDEF";
 
-gulong*
-gck_util_ulong_alloc (gulong value)
-{
-	return g_slice_dup (gulong, &value);
-}
-
-void
-gck_util_ulong_free (gpointer ptr_to_ulong)
-{
-	g_slice_free (gulong, ptr_to_ulong);
-}
-
-guint
-gck_util_ulong_hash (gconstpointer v)
-{
-	const signed char *p = v;
-	guint32 i, h = *p;
-	for(i = 0; i < sizeof (gulong); ++i)
-		h = (h << 5) - h + *(p++);
-	return h;
-}
-
-gboolean
-gck_util_ulong_equal (gconstpointer v1, gconstpointer v2)
-{
-	return *((const gulong*)v1) == *((const gulong*)v2);
-}
-
-CK_RV
-gck_util_return_data (CK_VOID_PTR output, CK_ULONG_PTR n_output,
-                      gconstpointer input, gsize n_input)
-{
-	g_return_val_if_fail (n_output, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (input || !n_input, CKR_GENERAL_ERROR);
-	
-	/* Just asking for the length */
-	if (!output) {
-		*n_output = n_input;
-		return CKR_OK;
-	}
-	
-	/* Buffer is too short */
-	if (n_input > *n_output) {
-		*n_output = n_input;
-		return CKR_BUFFER_TOO_SMALL;
-	}
-
-	*n_output = n_input;
-	if (n_input)
-		memcpy (output, input, n_input);
-	return CKR_OK;
-}
-
-CK_ULONG
-gck_util_next_handle (void)
-{
-	return (CK_ULONG)g_atomic_int_exchange_and_add (&next_handle, 1);
-}
-
 guchar*
-gck_util_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
+egg_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
 {
 	guchar *result;
 	guchar *decoded;
@@ -142,7 +79,7 @@
 }
 
 gchar* 
-gck_util_hex_encode (const guchar *data, gsize n_data)
+egg_hex_encode (const guchar *data, gsize n_data)
 {
 	gchar *result, *encoded;
 	guchar j;

Copied: trunk/egg/egg-hex.h (from r1460, /trunk/pkcs11/gck/gck-util.h)
==============================================================================
--- /trunk/pkcs11/gck/gck-util.h	(original)
+++ trunk/egg/egg-hex.h	Sun Jan 18 22:24:09 2009
@@ -19,39 +19,16 @@
  * 02111-1307, USA.  
  */
 
-#ifndef GCKUTIL_H_
-#define GCKUTIL_H_
+#ifndef EGG_HEX_H_
+#define EGG_HEX_H_
 
 #include <glib.h>
 
-#include <gcrypt.h>
-
-#include "pkcs11/pkcs11.h"
-
-guint                 gck_util_ulong_hash                         (gconstpointer ptr_to_ulong);
-
-gboolean              gck_util_ulong_equal                        (gconstpointer ptr_to_ulong_1, 
-                                                                   gconstpointer ptr_to_ulong_2);
-
-gulong*               gck_util_ulong_alloc                        (gulong value);
-
-void                  gck_util_ulong_free                         (gpointer ptr_to_ulong);
-
-CK_RV                 gck_util_return_data                        (CK_VOID_PTR output,
-                                                                   CK_ULONG_PTR n_output,
-                                                                   gconstpointer input,
-                                                                   gsize n_input);
-
-CK_RV                 gck_attribute_set_mpi                       (CK_ATTRIBUTE_PTR attr, 
-                                                                   gcry_mpi_t mpi);
-
-CK_ULONG              gck_util_next_handle                        (void);
-
-guchar*               gck_util_hex_decode                         (const gchar *data, 
+guchar*               egg_hex_decode                         (const gchar *data, 
                                                                    gssize n_data, 
                                                                    gsize *n_decoded);
 
-gchar*                gck_util_hex_encode                         (const guchar *data, 
+gchar*                egg_hex_encode                         (const guchar *data, 
                                                                    gsize n_data);
 
-#endif /* GCKUTIL_H_ */
+#endif /* EGG_HEX_H_ */

Copied: trunk/egg/egg-openssl.c (from r1460, /trunk/pkcs11/gck/gck-data-openssl.c)
==============================================================================
--- /trunk/pkcs11/gck/gck-data-openssl.c	(original)
+++ trunk/egg/egg-openssl.c	Sun Jan 18 22:24:09 2009
@@ -1,5 +1,5 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gck-data-openssl.c - OpenSSL compatibility functionality
+/* egg-openssl.c - OpenSSL compatibility functionality
 
    Copyright (C) 2007 Stefan Walter
 
@@ -23,15 +23,331 @@
 
 #include "config.h"
 
-#include "gck-crypto.h"
-#include "gck-data-openssl.h"
-#include "gck-util.h"
+#include "egg-hex.h"
+#include "egg-openssl.h"
+#include "egg-secure-memory.h"
+#include "egg-symkey.h"
 
 #include <gcrypt.h>
 #include <libtasn1.h>
 
 #include <glib.h>
 
+#include <ctype.h>
+#include <string.h>
+
+/* 
+ * PEM looks like:
+ * 
+ * 	-----BEGIN RSA PRIVATE KEY-----
+ * 	Proc-Type: 4,ENCRYPTED
+ * 	DEK-Info: DES-EDE3-CBC,704CFFD62FBA03E9
+ * 
+ * 	4AV/g0BiTeb07hzo4/Ct47HGhHEshMhBPGJ843QzuAinpZBbg3OxwPsQsLgoPhJL
+ * 	Bg6Oxyz9M4UN1Xlx6Lyo2lRT908mBP6dl/OItLsVArqAzM+e29KHQVNjV1h7xN9F
+ *	u84tOgZftKun+ZkQUOoRvMLLu4yV4CUraks9tgyXquugGba/tbeyj2MYsC8wwSJX
+ * 	....
+ * 	-----END RSA PRIVATE KEY-----
+ */
+ 
+#define PEM_SUFF          "-----"
+#define PEM_SUFF_L        5
+#define PEM_PREF_BEGIN    "-----BEGIN "
+#define PEM_PREF_BEGIN_L  11
+#define PEM_PREF_END      "-----END "
+#define PEM_PREF_END_L    9
+
+static void
+parse_header_lines (const gchar *hbeg, const gchar *hend, GHashTable **result)
+{
+	gchar **lines, **l;
+	gchar *line, *name, *value;
+	gchar *copy;
+	
+	copy = g_strndup (hbeg, hend - hbeg);
+	lines = g_strsplit (copy, "\n", 0);
+	g_free (copy);
+	
+	for (l = lines; l && *l; ++l) {
+		line = *l;
+		g_strstrip (line);
+		
+        	/* Look for the break between name: value */
+        	value = strchr (line, ':');
+        	if (value == NULL)
+        		continue;
+        		
+        	*value = 0;
+        	value = g_strdup (value + 1);
+        	g_strstrip (value);
+        	
+        	name = g_strdup (line);
+        	g_strstrip (name);
+        	
+        	if (!*result)
+        		*result = egg_openssl_headers_new ();
+        	g_hash_table_replace (*result, name, value);
+	}
+
+	g_strfreev (lines);
+} 
+
+static const gchar*
+pem_find_begin (const gchar *data, gsize n_data, GQuark *type)
+{
+	const gchar *pref, *suff;
+	gchar *stype;
+	
+	/* Look for a prefix */
+	pref = g_strstr_len ((gchar*)data, n_data, PEM_PREF_BEGIN);
+	if (!pref)
+		return NULL;
+		
+	n_data -= (pref - data) + PEM_PREF_BEGIN_L;
+	data = pref + PEM_PREF_BEGIN_L;
+		
+	/* Look for the end of that begin */
+	suff = g_strstr_len ((gchar*)data, n_data, PEM_SUFF);
+	if (!suff)
+		return NULL;
+		
+	/* Make sure on the same line */
+	if (memchr (pref, '\n', suff - pref))
+		return NULL;
+		
+	if (type) {
+		*type = 0;
+		pref += PEM_PREF_BEGIN_L;
+		g_assert (suff > pref);
+		stype = g_alloca (suff - pref + 1);
+		memcpy (stype, pref, suff - pref);
+		stype[suff - pref] = 0;
+		*type = g_quark_from_string (stype);
+	} 
+	
+	/* The byte after this ---BEGIN--- */
+	return suff + PEM_SUFF_L;
+}
+
+static const gchar*
+pem_find_end (const gchar *data, gsize n_data, GQuark type)
+{
+	const gchar *stype;
+	const gchar *pref;
+	gsize n_type;
+	
+	/* Look for a prefix */
+	pref = g_strstr_len (data, n_data, PEM_PREF_END);
+	if (!pref)
+		return NULL;
+		
+	n_data -= (pref - data) + PEM_PREF_END_L;
+	data = pref + PEM_PREF_END_L;
+	
+	/* Next comes the type string */
+	stype = g_quark_to_string (type);
+	n_type = strlen (stype);
+	if (strncmp ((gchar*)data, stype, n_type) != 0)
+		return NULL; 
+		
+	n_data -= n_type;
+	data += n_type;
+	
+	/* Next comes the suffix */
+	if (strncmp ((gchar*)data, PEM_SUFF, PEM_SUFF_L) != 0)
+		return NULL;
+		
+	/* The beginning of this ---END--- */
+	return pref;
+}
+
+static gboolean
+pem_parse_block (const gchar *data, gsize n_data, guchar **decoded, gsize *n_decoded,
+                 GHashTable **headers)
+{
+	const gchar *x, *hbeg, *hend;
+	const gchar *p, *end;
+	gint state = 0;
+	guint save = 0;
+	
+	g_assert (data);
+	g_assert (n_data);
+	
+	g_assert (decoded);
+	g_assert (n_decoded);
+	
+	p = data;
+	end = p + n_data;
+	
+	hbeg = hend = NULL;
+	
+	/* Try and find a pair of blank lines with only white space between */
+	while (hend == NULL) {
+		x = memchr (p, '\n', end - p);
+		if (!x)
+			break;
+		++x;
+		while (isspace (*x)) {
+			/* Found a second line, with only spaces between */
+			if (*x == '\n') {
+				hbeg = data;
+				hend = x;
+				break;
+			/* Found a space between two lines */
+			} else {
+				++x;
+			}
+		}
+		
+		/* Try next line */
+		p = x;
+	}
+
+	/* Headers found? */	
+	if (hbeg && hend) {
+		data = hend;
+		n_data = end - data;
+	}
+	
+	*n_decoded = (n_data * 3) / 4 + 1;
+	if (egg_secure_check (data))
+		*decoded = egg_secure_alloc (*n_decoded);
+	else
+		*decoded = g_malloc0 (*n_decoded);
+	g_return_val_if_fail (*decoded, FALSE);
+	
+	*n_decoded = g_base64_decode_step (data, n_data, *decoded, &state, &save);
+	if (!*n_decoded) {
+		egg_secure_free (*decoded);
+		return FALSE;
+	}
+	
+	if (headers && hbeg && hend) 
+		parse_header_lines (hbeg, hend, headers);
+	
+	return TRUE;
+}
+
+GHashTable*
+egg_openssl_headers_new (void)
+{
+	return g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+}
+
+guint
+egg_openssl_pem_parse (const guchar *data, gsize n_data, 
+                       EggOpensslPemCallback callback, gpointer user_data)
+{
+	const gchar *beg, *end;
+	guint nfound = 0;
+	guchar *decoded = NULL;
+	gsize n_decoded = 0;
+	GHashTable *headers = NULL;
+	GQuark type;
+	
+	g_return_val_if_fail (data, 0);
+	g_return_val_if_fail (n_data, 0);
+	g_return_val_if_fail (callback, 0);
+
+	while (n_data > 0) {
+		
+		/* This returns the first character after the PEM BEGIN header */
+		beg = pem_find_begin ((const gchar*)data, n_data, &type);
+		if (!beg)
+			break;
+			
+		g_assert (type);
+		
+		/* This returns the character position before the PEM END header */
+		end = pem_find_end ((const gchar*)beg, n_data - ((const guchar*)beg - data), type);
+		if (!end)
+			break;
+
+		if (beg != end) {
+			if (pem_parse_block (beg, end - beg, &decoded, &n_decoded, &headers)) {
+				(callback) (type, decoded, n_decoded, headers, user_data);
+				++nfound;
+				egg_secure_free (decoded);
+				if (headers)
+					g_hash_table_remove_all (headers);
+			}
+		}
+                     
+		/* Try for another block */
+		end += PEM_SUFF_L;
+		n_data -= (const guchar*)end - data; 
+		data = (const guchar*)end;
+	}
+	
+	if (headers)
+		g_hash_table_destroy (headers);
+
+	return nfound;
+}
+
+#ifdef UNTESTED_CODE
+
+static void 
+append_each_header (gpointer key, gpointer value, gpointer user_data)
+{
+	GString *string = (GString*)user_data;
+	
+	g_string_append (string, (gchar*)key);
+	g_string_append (string, ": ");
+	g_string_append (string, (gchar*)value);
+	g_string_append_c (string, '\n');
+}
+
+guchar*
+egg_openssl_pem_write (const guchar *data, gsize n_data, GQuark type, 
+                    GHashTable *headers, gsize *n_result)
+{
+	GString *string;
+	gint state, save;
+	gsize length, n_prefix;
+	
+	g_return_val_if_fail (data || !n_data, NULL);
+	g_return_val_if_fail (type, NULL);
+	g_return_val_if_fail (n_result, NULL);
+
+	string = g_string_sized_new (4096);
+	
+	/* The prefix */
+	g_string_append_len (string, PEM_PREF_BEGIN, PEM_PREF_BEGIN_L);
+	g_string_append (string, g_quark_to_string (type));
+	g_string_append_len (string, PEM_SUFF, PEM_SUFF_L);
+	g_string_append_c (string, '\n');
+	
+	/* The headers */
+	if (headers && g_hash_table_size (headers) > 0) {
+		g_hash_table_foreach (headers, append_each_header, string);
+		g_string_append_c (string, '\n');
+	}
+
+	/* Resize string to fit the base64 data. Algorithm from Glib reference */
+	length = n_data * 4 / 3 + n_data * 4 / (3 * 72) + 7;
+	n_prefix = string->len;
+	g_string_set_size (string, n_prefix + length);
+	
+	/* The actual base64 data */
+	state = save = 0;
+	length = g_base64_encode_step (data, n_data, TRUE, 
+	                               string->str + string->len, &state, &save);
+	g_string_set_size (string, n_prefix + length);
+	
+	/* The suffix */
+	g_string_append_c (string, '\n');
+	g_string_append_len (string, PEM_PREF_END, PEM_PREF_END_L);
+	g_string_append (string, g_quark_to_string (type));
+	g_string_append_len (string, PEM_SUFF, PEM_SUFF_L);
+	g_string_append_c (string, '\n');
+	
+	*n_result = string->len;
+	return (guchar*)g_string_free (string, FALSE);
+}
+
+#endif /* UNTESTED_CODE */
+
 /* ----------------------------------------------------------------------------
  * DEFINITIONS
  */
@@ -137,7 +453,7 @@
 /* ------------------------------------------------------------------------- */
 
 int
-gck_data_openssl_parse_algo (const char *name, int *mode)
+egg_openssl_parse_algo (const char *name, int *mode)
 {
 	static GQuark openssl_quarks[G_N_ELEMENTS(openssl_algos)] = { 0, };
 	static gsize openssl_quarks_inited = 0;
@@ -176,7 +492,7 @@
 		goto done;
 		
 	/* Parse the algorithm name */
-	*algo = gck_data_openssl_parse_algo (parts[0], mode);
+	*algo = egg_openssl_parse_algo (parts[0], mode);
 	if (!*algo)
 		goto done;
 	
@@ -188,7 +504,7 @@
 	/* Parse the IV */
 	ivlen = gcry_cipher_get_algo_blklen (*algo);
 	
-	*iv = gck_util_hex_decode (parts[1], strlen(parts[1]), &len);
+	*iv = egg_hex_decode (parts[1], strlen(parts[1]), &len);
 	if (!*iv || ivlen != len) {
 		g_free (*iv);
 		goto done;
@@ -201,10 +517,10 @@
 	return success;
 }
 
-GckDataResult
-gck_data_openssl_decrypt_block (const gchar *dekinfo, const gchar *password, 
-                                gssize n_password, const guchar *data, gsize n_data, 
-                                guchar **decrypted, gsize *n_decrypted)
+gboolean
+egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password, 
+                           gssize n_password, const guchar *data, gsize n_data, 
+                           guchar **decrypted, gsize *n_decrypted)
 {
 	gcry_cipher_hd_t ch;
 	guchar *key = NULL;
@@ -214,7 +530,7 @@
 	int mode = 0;
 	
 	if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
-		return GCK_DATA_UNRECOGNIZED;
+		return FALSE;
 		
 	ivlen = gcry_cipher_get_algo_blklen (algo);
 
@@ -222,42 +538,42 @@
 	g_return_val_if_fail (ivlen >= 8, FALSE);
 	
 	/* IV is already set from the DEK info */
-	if (!gck_crypto_symkey_generate_simple (algo, GCRY_MD_MD5, password, 
+	if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password, 
 	                                        n_password, iv, 8, 1, &key, NULL)) {
 		g_free (iv);
-		return GCK_DATA_FAILURE;
+		return FALSE;
 	}
 	
 	/* TODO: Use secure memory */
 	gcry = gcry_cipher_open (&ch, algo, mode, 0);
-	g_return_val_if_fail (!gcry, GCK_DATA_FAILURE);
+	g_return_val_if_fail (!gcry, FALSE);
 		
 	gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
-	g_return_val_if_fail (!gcry, GCK_DATA_UNRECOGNIZED);
-	gcry_free (key);
+	g_return_val_if_fail (!gcry, FALSE);
+	egg_secure_free (key);
 
 	/* 16 = 128 bits */
 	gcry = gcry_cipher_setiv (ch, iv, ivlen);
-	g_return_val_if_fail (!gcry, GCK_DATA_UNRECOGNIZED);
+	g_return_val_if_fail (!gcry, FALSE);
 	g_free (iv);
 	
 	/* Allocate output area */
 	*n_decrypted = n_data;
-	*decrypted = gcry_calloc_secure (n_data, 1);
+	*decrypted = egg_secure_alloc (n_data);
 
 	gcry = gcry_cipher_decrypt (ch, *decrypted, *n_decrypted, (void*)data, n_data);
 	if (gcry) {
-		gcry_free (*decrypted);
-		g_return_val_if_reached (GCK_DATA_FAILURE);
+		egg_secure_free (*decrypted);
+		g_return_val_if_reached (FALSE);
 	}
 	
 	gcry_cipher_close (ch);
 	
-	return GCK_DATA_SUCCESS;
+	return TRUE;
 }
 
 gboolean
-gck_data_openssl_encrypt_block (const gchar *dekinfo, const gchar *password, 
+egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password, 
                                 gssize n_password, const guchar *data, gsize n_data,
                                 guchar **encrypted, gsize *n_encrypted)
 {
@@ -279,7 +595,7 @@
 	g_return_val_if_fail (ivlen >= 8, FALSE);
 	
 	/* IV is already set from the DEK info */
-	if (!gck_crypto_symkey_generate_simple (algo, GCRY_MD_MD5, password, 
+	if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password, 
 	                                        n_password, iv, 8, 1, &key, NULL))
 		g_return_val_if_reached (FALSE);
 	
@@ -288,7 +604,7 @@
 		
 	gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
 	g_return_val_if_fail (!gcry, FALSE);
-	gcry_free (key);
+	egg_secure_free (key);
 
 	/* 16 = 128 bits */
 	gcry = gcry_cipher_setiv (ch, iv, ivlen);
@@ -315,11 +631,11 @@
 	
 	/* Encrypt the padded block */
 	if (n_overflow) {
-		padded = gcry_calloc_secure (ivlen, 1);
+		padded = egg_secure_alloc (ivlen);
 		memset (padded, 0, ivlen);
 		memcpy (padded, data + n_batch, n_overflow);
 		gcry = gcry_cipher_encrypt (ch, *encrypted + n_batch, ivlen, padded, ivlen);
-		gcry_free (padded);
+		egg_secure_free (padded);
 		if (gcry) {
 			g_free (*encrypted);
 			g_return_val_if_reached (FALSE);
@@ -331,7 +647,7 @@
 }
 
 const gchar*
-gck_data_openssl_get_dekinfo (GHashTable *headers)
+egg_openssl_get_dekinfo (GHashTable *headers)
 {
 	const gchar *val;
 	if (!headers)
@@ -345,7 +661,7 @@
 }
 
 const gchar*
-gck_data_openssl_prep_dekinfo (GHashTable *headers)
+egg_openssl_prep_dekinfo (GHashTable *headers)
 {
 	gchar *dekinfo, *hex;
 	gsize ivlen;
@@ -358,7 +674,7 @@
 	gcry_create_nonce (iv, ivlen);
 	
 	/* And encode it into the string */
-	hex = gck_util_hex_encode (iv, ivlen);
+	hex = egg_hex_encode (iv, ivlen);
 	g_return_val_if_fail (hex, NULL);
 	dekinfo = g_strdup_printf ("DES-EDE3-CBC,%s", hex);
 	g_free (hex);

Copied: trunk/egg/egg-openssl.h (from r1460, /trunk/pkcs11/gck/gck-data-openssl.h)
==============================================================================
--- /trunk/pkcs11/gck/gck-data-openssl.h	(original)
+++ trunk/egg/egg-openssl.h	Sun Jan 18 22:24:09 2009
@@ -1,5 +1,5 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* gck-data-openssl.h - OpenSSL compatibility functionality
+/* egg-openssl.h - OpenSSL compatibility functionality
 
    Copyright (C) 2007 Stefan Walter
 
@@ -21,23 +21,36 @@
    Author: Stef Walter <stef memberwebs com>
 */
 
-#ifndef GCKDATAOPENSSL_H_
-#define GCKDATAOPENSSL_H_
+#ifndef EGG_OPENSSL_H_
+#define EGG_OPENSSL_H_
 
-#include "gck-data-types.h"
+#include <glib.h>
 
-int              gck_data_openssl_parse_algo        (const gchar *name, int *mode);
+typedef void (*EggOpensslPemCallback) (GQuark type, const guchar *data, gsize n_data,
+                                       GHashTable *headers, gpointer user_data);
 
-gboolean         gck_data_openssl_encrypt_block     (const gchar *dekinfo, const gchar *password, 
-                                                     gssize n_password, const guchar *data, gsize n_data,
-                                                     guchar **encrypted, gsize *n_encrypted);
+GHashTable*      egg_openssl_headers_new       (void);
 
-GckDataResult    gck_data_openssl_decrypt_block     (const gchar *dekinfo, const gchar *password, 
-                                                     gssize n_password, const guchar *data, gsize n_data, 
-                                                     guchar **decrypted, gsize *n_decrypted);
+guint            egg_openssl_pem_parse         (const guchar *data, gsize n_data, 
+                                                EggOpensslPemCallback callback, 
+                                                gpointer user_data);
 
-const gchar*     gck_data_openssl_get_dekinfo       (GHashTable *headers);
+guchar*          egg_openssl_pem_write         (const guchar *data, gsize n_data, 
+                                                GQuark type, GHashTable *headers,
+                                                gsize *n_result);
 
-const gchar*     gck_data_openssl_prep_dekinfo      (GHashTable *headers);
+int              egg_openssl_parse_algo        (const gchar *name, int *mode);
 
-#endif /* GCKDATAOPENSSL_H_ */
+gboolean         egg_openssl_encrypt_block     (const gchar *dekinfo, const gchar *password, 
+                                                gssize n_password, const guchar *data, gsize n_data,
+                                                guchar **encrypted, gsize *n_encrypted);
+
+gboolean         egg_openssl_decrypt_block     (const gchar *dekinfo, const gchar *password, 
+                                                gssize n_password, const guchar *data, gsize n_data, 
+                                                guchar **decrypted, gsize *n_decrypted);
+
+const gchar*     egg_openssl_get_dekinfo       (GHashTable *headers);
+
+const gchar*     egg_openssl_prep_dekinfo      (GHashTable *headers);
+
+#endif /* EGG_OPENSSL_H_ */

Copied: trunk/egg/egg-symkey.c (from r1461, /trunk/pkcs11/gck/gck-crypto.c)
==============================================================================
--- /trunk/pkcs11/gck/gck-crypto.c	(original)
+++ trunk/egg/egg-symkey.c	Sun Jan 18 22:24:09 2009
@@ -21,960 +21,72 @@
 
 #include "config.h"
 
-#include "gck-crypto.h"
+#include "egg-asn1.h"
+#include "egg-secure-memory.h"
+#include "egg-symkey.h"
 
-#include "egg/egg-secure-memory.h"
-
-/* ----------------------------------------------------------------------------
- * INTERNAL
+/* -----------------------------------------------------------------------------
+ * QUARKS
  */
 
-static gcry_sexp_t
-sexp_get_childv (gcry_sexp_t sexp, va_list va)
-{
-	gcry_sexp_t at = NULL;
-	gcry_sexp_t child;
-	const char *name;
-	
-	for(;;) {
-		name = va_arg (va, const char*);
-		if (!name)
-			break;
-
-		child = gcry_sexp_find_token (at ? at : sexp, name, 0);
-		gcry_sexp_release (at);
-		at = child;
-		if (at == NULL)
-			break;
-	}
-	
-	va_end (va);
-
-	return at;
-}
-
-static CK_RV
-data_to_sexp (const gchar *format, guint nbits, GckCryptoPadding padding, 
-              CK_BYTE_PTR data, CK_ULONG n_data, gcry_sexp_t *sexp)
-{
-	guchar *padded = NULL;
-	gcry_error_t gcry;
-	gcry_mpi_t mpi;
-	gsize n_padded;
-
-	g_assert (format);
-	g_assert (sexp);	
-	
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
-	if (padding) {
-		padded = (padding) (nbits, data, n_data, &n_padded);
-		if (!padded)
-			return CKR_DATA_LEN_RANGE;
-	}
-		
-	/* Prepare the input s expression */
-	gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, 
-                              padded ? padded : data, 
-	                      padded ? n_padded : n_data, NULL);
-	g_free (padded);
-
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
-	gcry = gcry_sexp_build (sexp, NULL, format, mpi);
-	gcry_mpi_release (mpi);
-
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
-	g_assert (*sexp);
-	return CKR_OK;
-} 
-
-/* For the sake of checking arguments */
-static CK_RV
-sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data, 
-              CK_ULONG *n_data, GckCryptoPadding padding, 
-              ...) G_GNUC_NULL_TERMINATED;
-
-static CK_RV
-sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data, 
-              CK_ULONG *n_data, GckCryptoPadding padding, ...)
-{
-	gcry_sexp_t at = NULL;
-	gsize n_block, offset, len;
-	gcry_mpi_t mpi = NULL;
-	guchar *block;
-	va_list va;
-	gcry_error_t gcry;
-	
-	g_assert (sexp);
-	g_assert (data);
-	g_assert (n_data);
-	g_assert (bits);
-
-	/* First try and dig out sexp child based on arguments */
-	va_start (va, padding);
-	at = sexp_get_childv (sexp, va);
-	va_end (va);
-	
-	/* It's expected we would find it */
-	g_return_val_if_fail (at != NULL, CKR_GENERAL_ERROR);
-
-	/* Parse out the MPI */
-	mpi = gcry_sexp_nth_mpi (at, 1, GCRYMPI_FMT_USG);
-	g_return_val_if_fail (at != NULL, CKR_GENERAL_ERROR);
-	gcry_sexp_release (at);
-	
-	/* Print out the MPI into the end of a temporary buffer */
-	n_block = (bits + 7) / 8;
-	gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &len, mpi);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (len <= n_block, CKR_GENERAL_ERROR);
-	offset = n_block - len;
-	block = g_malloc0 (n_block);
-	memset (block, 0, offset);
-	gcry = gcry_mpi_print (GCRYMPI_FMT_USG, block + offset, len, &len, mpi);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (len == n_block - offset, CKR_GENERAL_ERROR);
-	gcry_mpi_release (mpi);
-		
-	/* Pad it properly if necessary */
-	if (padding != NULL) {
-		guchar *padded = (padding) (bits, block, n_block, &n_block);
-		g_free (block);
-		if (!padded)
-			return CKR_DATA_LEN_RANGE;
-		block = padded;
-	}
-	
-	/* Now stuff it into the output buffer */
-	if (n_block > *n_data)
-		return CKR_BUFFER_TOO_SMALL;
-
-	memcpy (data, block, n_block);
-	*n_data = n_block;
-	g_free (block);
-	
-	return CKR_OK;
-}
+static GQuark OID_PBE_MD2_DES_CBC;
+static GQuark OID_PBE_MD5_DES_CBC;
+static GQuark OID_PBE_MD2_RC2_CBC;
+static GQuark OID_PBE_MD5_RC2_CBC;
+static GQuark OID_PBE_SHA1_DES_CBC;
+static GQuark OID_PBE_SHA1_RC2_CBC;
+static GQuark OID_PBES2;
+static GQuark OID_PBKDF2;
+
+static GQuark OID_DES_CBC;
+static GQuark OID_DES_RC2_CBC;
+static GQuark OID_DES_EDE3_CBC;
+static GQuark OID_DES_RC5_CBC;
+
+static GQuark OID_PKCS12_PBE_ARCFOUR_SHA1;
+static GQuark OID_PKCS12_PBE_RC4_40_SHA1;
+static GQuark OID_PKCS12_PBE_3DES_SHA1;
+static GQuark OID_PKCS12_PBE_2DES_SHA1;
+static GQuark OID_PKCS12_PBE_RC2_128_SHA1;
+static GQuark OID_PKCS12_PBE_RC2_40_SHA1;
 
 static void
-fill_random_nonzero (guchar *data, gsize n_data)
-{
-	guchar *rnd;
-	guint n_zero, i, j;
-	
-	gcry_randomize (data, n_data, GCRY_STRONG_RANDOM);
-
-	/* Find any zeros in random data */
-	n_zero = 0;
-	for (i = 0; i < n_data; ++i) {
-		if (data[i] == 0x00)
-			++n_zero;
-	}
-
-	while (n_zero > 0) {
-		rnd = gcry_random_bytes (n_zero, GCRY_STRONG_RANDOM);
-		n_zero = 0;
-		for (i = 0, j = 0; i < n_data; ++i) {
-			if (data[i] != 0x00)
-				continue;
-				
-			/* Use some of the replacement data */
-			data[i] = rnd[j];
-			++j;
-			
-			/* It's zero again :( */
-			if (data[i] == 0x00)
-				n_zero++;
-		}
-		
-		gcry_free (rnd);
-	}
-}
-
-static guchar*
-unpad_rsa_pkcs1 (guchar bt, guint n_modulus, const guchar* padded,
-                 gsize n_padded, gsize *n_raw)
-{ 
-	const guchar *at;
-	guchar *raw;
-	
-	/* The absolute minimum size including padding */
-	g_return_val_if_fail (n_modulus / 8 >= 3 + 8, NULL);
-	
-	if (n_padded != n_modulus / 8)
-		return NULL;
-		
-	/* Check the header */
-	if (padded[0] != 0x00 || padded[1] != bt)
-		return NULL;
-	
-	/* The first zero byte after the header */
-	at = memchr (padded + 2, 0x00, n_padded - 2);
-	if (!at)
-		return NULL;
-		
-	++at;
-	*n_raw = n_padded - (at - padded);
-	raw = g_new0 (guchar, *n_raw);
-	memcpy (raw, at, *n_raw);
-	return raw;
-}
-
-
-/* ----------------------------------------------------------------------------
- * PUBLIC
- */
-
-CK_RV
-gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data, 
-                    CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
-{
-	int algorithm;
-	CK_RV rv;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-	
-	if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-
-	/* 
-	 * The algorithm checks below are merely sanity checks.
-	 * Other code should have checed this at an earlier stage
-	 * and return the right error codes if invalid.
-	 */
-	
-	switch (mech) {
-	case CKM_RSA_PKCS:
-		g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR); 
-		rv = gck_crypto_encrypt_rsa (sexp, gck_crypto_rsa_pad_two, data, n_data, encrypted, n_encrypted);
-		break;
-	case CKM_RSA_X_509:
-		g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
-		rv = gck_crypto_encrypt_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, encrypted, n_encrypted);
-		break;
-	default:
-		/* Again shouldn't be reached */
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-	};
-	
-	return rv;	
-}
-
-CK_RV
-gck_crypto_encrypt_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data, 
-                        CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
-{
-	gcry_sexp_t splain, sdata;
-	gcry_error_t gcry;
-	guint nbits;
-	CK_RV rv;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (n_encrypted, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
-	nbits = gcry_pk_get_nbits (sexp);
-	g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
-	/* Just want to know the length */
-	if (!encrypted) {
-		*n_encrypted = (nbits + 7) / 8;
-		return CKR_OK;
-	}
-
-	/* Prepare the input s expression */
-	rv = data_to_sexp ("(data (flags raw) (value %m))", 
-	                   nbits, padding, data, n_data, &splain);
-	if (rv != CKR_OK)
-		return rv;
-	
-	/* Do the magic */
-	gcry = gcry_pk_encrypt (&sdata, splain, sexp);
-	gcry_sexp_release (splain);
-	
-	/* TODO: Certain codes should be returned (data too big etc... ) */
-	if (gcry) {
-		g_message ("encrypting of the data failed: %s", gcry_strerror (gcry));
-		return CKR_FUNCTION_FAILED;
-	}
-
-	/* Now extract and send it back out */
-	rv = sexp_to_data (sdata, nbits, encrypted, n_encrypted, NULL, "enc-val", "rsa", "a", NULL);
-	gcry_sexp_release (sdata);
-	
-	return rv;
-}
-
-CK_RV
-gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encrypted, 
-                    CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
-{
-	int algorithm;
-	CK_RV rv;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
-	
-	if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-
-	/* 
-	 * The algorithm checks below are merely sanity checks.
-	 * Other code should have checed this at an earlier stage
-	 * and return the right error codes if invalid.
-	 */
-	
-	switch (mech) {
-	case CKM_RSA_PKCS:
-		g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR); 
-		rv = gck_crypto_decrypt_rsa (sexp, gck_crypto_rsa_unpad_two, encrypted, n_encrypted, data, n_data);
-		break;
-	case CKM_RSA_X_509:
-		g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
-		rv = gck_crypto_decrypt_rsa (sexp, NULL, encrypted, n_encrypted, data, n_data);
-		break;
-	default:
-		/* Again shouldn't be reached */
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-	};
-	
-	return rv;	
-}
-
-CK_RV
-gck_crypto_decrypt_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR encrypted, 
-                        CK_ULONG n_encrypted, CK_BYTE_PTR data, CK_ULONG_PTR n_data)
-{
-	gcry_sexp_t splain, sdata;
-	gcry_error_t gcry;
-	guint nbits;
-	CK_RV rv;
-
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (n_data, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (encrypted, CKR_ARGUMENTS_BAD);
-
-	nbits = gcry_pk_get_nbits (sexp);
-	g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
-	/* Just want to know the length */
-	if (!data) {
-		*n_data = (nbits + 7) / 8;
-		return CKR_OK;
-	}
-	
-	if (n_encrypted != (nbits + 7) / 8) 
-		return CKR_DATA_LEN_RANGE;
-	
-	/* Prepare the input s expression */
-	rv = data_to_sexp ("(enc-val (flags) (rsa (a %m)))", 
-	                   nbits, NULL, encrypted, n_encrypted, &sdata);
-	if (rv != CKR_OK)
-		return rv;
-
-	/* Do the magic */
-	gcry = gcry_pk_decrypt (&splain, sdata, sexp);
-	gcry_sexp_release (sdata);
-
-	/* TODO: Certain codes should be returned (data too big etc... ) */
-	if (gcry) {
-		g_message ("decrypting of the data failed: %s", gcry_strerror (gcry));
-		return CKR_FUNCTION_FAILED;
-	}
-
-	/* Now extract and send it back out */
-	rv = sexp_to_data (splain, nbits, data, n_data, padding, "value", NULL);
-	gcry_sexp_release (splain);
-	
-	return rv;
-}
-
-CK_RV
-gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data, 
-                 CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
-{
-	int algorithm;
-	CK_RV rv;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-	
-	if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-
-	/* 
-	 * The algorithm checks below are merely sanity checks.
-	 * Other code should have checed this at an earlier stage
-	 * and return the right error codes if invalid.
-	 */
-	
-	switch (mech) {
-	case CKM_RSA_PKCS:
-		g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR); 
-		rv = gck_crypto_sign_rsa (sexp, gck_crypto_rsa_pad_one, data, n_data, signature, n_signature);
-		break;
-	case CKM_RSA_X_509:
-		g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
-		rv = gck_crypto_sign_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, signature, n_signature);
-		break;
-	case CKM_DSA:
-		g_return_val_if_fail (algorithm == GCRY_PK_DSA, CKR_GENERAL_ERROR);
-		rv = gck_crypto_sign_dsa (sexp, data, n_data, signature, n_signature);
-		break;
-	default:
-		/* Again shouldn't be reached */
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-	};
-	
-	return rv;
-}
-
-CK_RV
-gck_crypto_sign_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data, 
-                     CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
-{
-	gcry_sexp_t ssig, sdata;
-	guint nbits; 
-	gcry_error_t gcry;
-	CK_RV rv;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
-	nbits = gcry_pk_get_nbits (sexp);
-	g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-
-	/* Just want to know the length */
-	if (!signature) {
-		*n_signature = (nbits + 7) / 8;
-		return CKR_OK;
-	}
-	
-	/* Prepare the input sexp */
-	rv = data_to_sexp ("(data (flags raw) (value %m))", 
-	                    nbits, padding, data, n_data, &sdata);
-	if (rv != CKR_OK)
-		return rv;
-
-	/* Do the magic */
-	gcry = gcry_pk_sign (&ssig, sdata, sexp);
-	gcry_sexp_release (sdata);
-
-	/* TODO: Certain codes should be returned (data too big etc... ) */
-	if (gcry) {
-		g_message ("signing of the data failed: %s", gcry_strerror (gcry));
-		return CKR_FUNCTION_FAILED;
-	}
-
-	/* Now extract and send it back out */
-	rv = sexp_to_data (ssig, nbits, signature, n_signature, NULL, "rsa", "s", NULL);
-	gcry_sexp_release (ssig);
-	
-	return rv;
-}
-
-CK_RV
-gck_crypto_sign_dsa (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data, 
-                     CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
-{
-	gcry_sexp_t ssig, splain;
-	gcry_error_t gcry;
-	gcry_mpi_t mpi;
-	CK_ULONG size;
-	CK_RV rv;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (n_signature, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
-	if (n_data != 20)
-		return CKR_DATA_LEN_RANGE;
-	
-	/* If no output, then don't process */
-	if (!signature) {
-		*n_signature = 40;
-		return CKR_OK;
-	} else if (*n_signature < 40) {
-		*n_signature = 40;
-		return CKR_BUFFER_TOO_SMALL;
-	}
-				
-	/* Prepare the input s-expression */
-	gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-	gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
-	gcry_mpi_release (mpi);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
-	/* Do the magic */
-	gcry = gcry_pk_sign (&ssig, splain, sexp);
-	gcry_sexp_release (splain);
-	
-	/* TODO: Certain codes should be returned (data too big etc... ) */
-	if (gcry) {
-		g_message ("signing of the data failed: %s", gcry_strerror (gcry));
-		return CKR_FUNCTION_FAILED;
-	}
-
-	g_assert (*n_signature >= 40);
-
-	size = 20;
-	rv = sexp_to_data (ssig, 20 * 8, signature, &size, NULL, "dsa", "r", NULL);
-	if (rv == CKR_OK) {
-		g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
-		rv = sexp_to_data (ssig, 20 * 8, signature + 20, &size, NULL, "dsa", "s", NULL);
-		if (rv == CKR_OK) {
-			g_return_val_if_fail (size == 20, CKR_GENERAL_ERROR);
-			*n_signature = 40;
-		}
-	}
-	
-	gcry_sexp_release (ssig);
-	return CKR_OK;
-}
-
-CK_RV
-gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data, 
-                   CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
-{
-	int algorithm;
-	CK_RV rv;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-	
-	if (!gck_crypto_sexp_parse_key (sexp, &algorithm, NULL, NULL))
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-
-	/* 
-	 * The algorithm checks below are merely sanity checks.
-	 * Other code should have checed this at an earlier stage
-	 * and return the right error codes if invalid.
-	 */
-	
-	switch (mech) {
-	case CKM_RSA_PKCS:
-		g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR); 
-		rv = gck_crypto_verify_rsa (sexp, gck_crypto_rsa_pad_one, data, n_data, signature, n_signature);
-		break;
-	case CKM_RSA_X_509:
-		g_return_val_if_fail (algorithm == GCRY_PK_RSA, CKR_GENERAL_ERROR);
-		rv = gck_crypto_verify_rsa (sexp, gck_crypto_rsa_pad_raw, data, n_data, signature, n_signature);
-		break;
-	case CKM_DSA:
-		g_return_val_if_fail (algorithm == GCRY_PK_DSA, CKR_GENERAL_ERROR);
-		rv = gck_crypto_verify_dsa (sexp, data, n_data, signature, n_signature);
-		break;
-	default:
-		/* Again shouldn't be reached */
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-	};
-	
-	return rv;
-}
-
-CK_RV
-gck_crypto_verify_rsa (gcry_sexp_t sexp, GckCryptoPadding padding, CK_BYTE_PTR data, 
-                       CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG n_signature)
-{
-	gcry_sexp_t ssig, sdata;
-	gcry_error_t gcry;
-	guint nbits;
-	CK_RV rv;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
-	/* The key size */
-	nbits = gcry_pk_get_nbits (sexp);
-	g_return_val_if_fail (nbits > 0, CKR_GENERAL_ERROR);
-	
-	if (n_signature != (nbits + 7) / 8)
-		return CKR_SIGNATURE_LEN_RANGE;
-
-	/* Prepare the input s expressions */
-	rv = data_to_sexp ("(data (flags raw) (value %m))", 
-	                   nbits, padding, data, n_data, &sdata);
-	if (rv != CKR_OK)
-		return rv;
-
-	rv = data_to_sexp ("(sig-val (rsa (s %m)))", 
-	                   nbits, NULL, signature, n_signature, &ssig);
-	if (rv != CKR_OK) {
-		gcry_sexp_release (sdata);
-		return rv;
-	}
-		
-	/* Do the magic */
-	gcry = gcry_pk_verify (ssig, sdata, sexp);
-	gcry_sexp_release (sdata);
-	gcry_sexp_release (ssig);
-	
-	/* TODO: See if any other codes should be mapped */
-	if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
-		return CKR_SIGNATURE_INVALID;
-	} else if (gcry) {
-		g_message ("signing of the data failed: %s", gcry_strerror (gcry));
-		return CKR_FUNCTION_FAILED;
-	}
-
-	return CKR_OK;
-}
-
-CK_RV
-gck_crypto_verify_dsa (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data, 
-                       CK_BYTE_PTR signature, CK_ULONG n_signature)
+init_quarks (void)
 {
-	gcry_sexp_t ssig, splain;
-	gcry_error_t gcry;
-	gcry_mpi_t mpi, mpi2;
-	
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (signature, CKR_ARGUMENTS_BAD);
-	g_return_val_if_fail (data, CKR_ARGUMENTS_BAD);
-
-	if (n_data != 20)
-		return CKR_DATA_LEN_RANGE;				
-	if (n_signature != 40)
-		return CKR_SIGNATURE_LEN_RANGE;
-
-	/* Prepare the input s-expressions */
-	gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, data, n_data, NULL);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-	gcry = gcry_sexp_build (&splain, NULL, "(data (flags raw) (value %m))", mpi);
-	gcry_mpi_release (mpi);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-
-	gcry = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, signature, 20, NULL);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-	gcry = gcry_mpi_scan (&mpi2, GCRYMPI_FMT_USG, signature + 20, 20, NULL);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-	gcry = gcry_sexp_build (&ssig, NULL, "(sig-val (dsa (r %m) (s %m)))", mpi, mpi2);
-	gcry_mpi_release (mpi);
-	gcry_mpi_release (mpi2);
-	g_return_val_if_fail (gcry == 0, CKR_GENERAL_ERROR);
-	
-	/* Do the magic */
-	gcry = gcry_pk_verify (ssig, splain, sexp);
-	gcry_sexp_release (splain);
-	gcry_sexp_release (ssig);
-	
-	/* TODO: See if any other codes should be mapped */
-	if (gcry_err_code (gcry) == GPG_ERR_BAD_SIGNATURE) {
-		return CKR_SIGNATURE_INVALID;
-	} else if (gcry) {
-		g_message ("signing of the data failed: %s", gcry_strerror (gcry));
-		return CKR_FUNCTION_FAILED;
-	}
-
-	return CKR_OK;
-}
+	static volatile gsize quarks_inited = 0;
 
-CK_RV 
-gck_crypto_perform (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_ATTRIBUTE_TYPE method, 
-                    CK_BYTE_PTR bufone, CK_ULONG n_bufone, CK_BYTE_PTR buftwo, CK_ULONG_PTR n_buftwo)
-{
-	g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (method, CKR_GENERAL_ERROR);
-	g_return_val_if_fail (n_buftwo, CKR_GENERAL_ERROR);
-	
-	switch (method) {
-	case CKA_ENCRYPT:
-		return gck_crypto_encrypt (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
-	case CKA_DECRYPT:
-		return gck_crypto_decrypt (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
-	case CKA_SIGN:
-		return gck_crypto_sign (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
-	case CKA_VERIFY:
-		return gck_crypto_verify (sexp, mech, bufone, n_bufone, buftwo, *n_buftwo);
-	default:
-		g_return_val_if_reached (CKR_GENERAL_ERROR);
-	}
-}
+	if (g_once_init_enter (&quarks_inited)) {
 
-/* ----------------------------------------------------------------------------
- * SEXP FUNCTIONS
- */
+		#define QUARK(name, value) \
+			name = g_quark_from_static_string(value)
 
-#define PUBLIC_KEY "public-key"
-#define PUBLIC_KEY_L 10
-#define PRIVATE_KEY "private-key"
-#define PRIVATE_KEY_L 11
-
-gboolean
-gck_crypto_sexp_parse_key (gcry_sexp_t s_key, int *algorithm, gboolean *is_private, 
-                           gcry_sexp_t *numbers)
-{
-	gboolean ret = FALSE;
-	gcry_sexp_t child = NULL;
-	gchar *str = NULL;
-  	const gchar *data;
-  	gsize n_data;
-  	gboolean priv;
-  	int algo;
-
-	data = gcry_sexp_nth_data (s_key, 0, &n_data);
-	if (!data) 
-		goto done;
-
-	if (n_data == PUBLIC_KEY_L && strncmp (data, PUBLIC_KEY, PUBLIC_KEY_L) == 0)
-		priv = FALSE;
-	else if (n_data == PRIVATE_KEY_L && strncmp (data, PRIVATE_KEY, PRIVATE_KEY_L) == 0)
-		priv = TRUE;
-	else
-		goto done;
-
-	child = gcry_sexp_nth (s_key, 1);
-	if (!child)
-		goto done;
+		QUARK (OID_PBE_MD2_DES_CBC, "1.2.840.113549.1.5.1");
+		QUARK (OID_PBE_MD5_DES_CBC, "1.2.840.113549.1.5.3");
+		QUARK (OID_PBE_MD2_RC2_CBC, "1.2.840.113549.1.5.4");
+		QUARK (OID_PBE_MD5_RC2_CBC, "1.2.840.113549.1.5.6");
+		QUARK (OID_PBE_SHA1_DES_CBC, "1.2.840.113549.1.5.10");
+		QUARK (OID_PBE_SHA1_RC2_CBC, "1.2.840.113549.1.5.11");
 		
-	data = gcry_sexp_nth_data (child, 0, &n_data);
-	if (!data)
-		goto done;
+		QUARK (OID_PBES2, "1.2.840.113549.1.5.13");
 		
-	str = g_alloca (n_data + 1);
-	memcpy (str, data, n_data);
-	str[n_data] = 0;
-	
-	algo = gcry_pk_map_name (str);
-	if (!algo)
-		goto done;
-
-	/* Yay all done */
-	if (algorithm)
-		*algorithm = algo;
-	if (numbers) {
-		*numbers = child;
-		child = NULL;
-	}
-	if (is_private)
-		*is_private = priv;
-
-	ret = TRUE;
-	
-done:
-	gcry_sexp_release (child);
-	return ret;
-}
-
-static gcry_sexp_t
-rsa_numbers_to_public (gcry_sexp_t rsa)
-{
-	gcry_sexp_t pubkey = NULL;
-	gcry_mpi_t n, e;
-	gcry_error_t gcry;
-	
-	n = e = NULL;
-	
-	if (!gck_crypto_sexp_extract_mpi (rsa, &n, "n", NULL) || 
-	    !gck_crypto_sexp_extract_mpi (rsa, &e, "e", NULL))
-	    	goto done;
-	    	
-	gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (rsa (n %m) (e %m)))",
-	                        n, e);
-	if (gcry)
-		goto done;
-	g_assert (pubkey);
-	
-done:
-	gcry_mpi_release (n);
-	gcry_mpi_release (e);
-
-	return pubkey;
-}
-
-static gcry_sexp_t
-dsa_numbers_to_public (gcry_sexp_t dsa)
-{
-	gcry_mpi_t p, q, g, y;
-	gcry_sexp_t pubkey = NULL;
-	gcry_error_t gcry;
-	
-	p = q = g = y = NULL;
-	
-	if (!gck_crypto_sexp_extract_mpi (dsa, &p, "p", NULL) || 
-	    !gck_crypto_sexp_extract_mpi (dsa, &q, "q", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (dsa, &g, "g", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (dsa, &y, "y", NULL))
-	    	goto done;
-	    	
-	gcry = gcry_sexp_build (&pubkey, NULL, "(public-key (dsa (p %m) (q %m) (g %m) (y %m)))",
-	                        p, q, g, y);
-	if (gcry)
-		goto done;
-	g_assert (pubkey);
-	
-done:
-	gcry_mpi_release (p);
-	gcry_mpi_release (q);
-	gcry_mpi_release (g);
-	gcry_mpi_release (y);
-
-	return pubkey;
-}
-
-gboolean
-gck_crypto_sexp_key_to_public (gcry_sexp_t privkey, gcry_sexp_t *pubkey)
-{
-	gcry_sexp_t numbers;
-	int algorithm;
-
-	if (!gck_crypto_sexp_parse_key (privkey, &algorithm, NULL, &numbers))
-		g_return_val_if_reached (FALSE);
+		QUARK (OID_PBKDF2, "1.2.840.113549.1.5.12");
 		
-	switch (algorithm) {
-	case GCRY_PK_RSA:
-		*pubkey = rsa_numbers_to_public (numbers);
-		break;
-	case GCRY_PK_DSA:
-		*pubkey = dsa_numbers_to_public (numbers);
-		break;
-	default:
-		g_return_val_if_reached (FALSE);
-	} 
-	
-	gcry_sexp_release (numbers);
-	return *pubkey ? TRUE : FALSE;
-}
-
-gboolean
-gck_crypto_sexp_extract_mpi (gcry_sexp_t sexp, gcry_mpi_t *mpi, ...)
-{
-	gcry_sexp_t at = NULL;
-	va_list va;
-	
-	g_assert (sexp);
-	g_assert (mpi);
-	
-	va_start (va, mpi);
-	at = sexp_get_childv (sexp, va);
-	va_end (va);
-	
-	*mpi = NULL;
-	if (at)
-		*mpi = gcry_sexp_nth_mpi (at ? at : sexp, 1, GCRYMPI_FMT_USG);
-	if (at)
-		gcry_sexp_release (at);
-
-	return (*mpi) ? TRUE : FALSE;
-}
-
-void
-gck_crypto_sexp_dump (gcry_sexp_t sexp)
-{
-	gsize len;
-	gchar *buf;
-	
-	len = gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
-	buf = g_malloc (len);
-	gcry_sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, len);
-	g_printerr ("%s", buf);
-	g_free (buf);
-}
-
-/* ----------------------------------------------------------------------------
- * PADDING FUNCTIONS
- */
-
-
-guchar*
-gck_crypto_rsa_pad_raw (guint n_modulus, const guchar* raw,
-                        gsize n_raw, gsize *n_padded)
-{
-	gint total, n_pad;
-	guchar *padded;
-
-	/*
-	 * 0x00 0x00 0x00 ... 0x?? 0x?? 0x?? ...
-         *   padding               data
-         */
-
-	total = n_modulus / 8;
-	n_pad = total - n_raw;
-	if (n_pad < 0) /* minumum padding */
-		return NULL;
-
-	padded = g_new0 (guchar, total);
-	memset (padded, 0x00, n_pad);
-	memcpy (padded + n_pad, raw, n_raw);
-	
-	*n_padded = total;
-	return padded;
-}
-
-guchar*
-gck_crypto_rsa_pad_one (guint n_modulus, const guchar* raw, 
-                        gsize n_raw, gsize *n_padded)
-{
-	gint total, n_pad;
-	guchar *padded;
-
-	/*
-	 * 0x00 0x01 0xFF 0xFF ... 0x00 0x?? 0x?? 0x?? ...
-         *      type  padding              data
-         */
-
-	total = n_modulus / 8;
-	n_pad = total - 3 - n_raw;
-	if (n_pad < 8) /* minumum padding */
-		return NULL;
-
-	padded = g_new0 (guchar, total);
-	padded[1] = 1; /* Block type */
-	memset (padded + 2, 0xff, n_pad);
-	memcpy (padded + 3 + n_pad, raw, n_raw); 
-	
-	*n_padded = total;
-	return padded;
-}
-
-guchar*
-gck_crypto_rsa_pad_two (guint n_modulus, const guchar* raw, 
-                        gsize n_raw, gsize *n_padded)
-{
-	gint total, n_pad;
-	guchar *padded;
-
-	/*
-	 * 0x00 0x01 0x?? 0x?? ... 0x00 0x?? 0x?? 0x?? ...
-         *      type  padding              data
-         */
-
-	total = n_modulus / 8;
-	n_pad = total - 3 - n_raw;
-	if (n_pad < 8) /* minumum padding */
-		return NULL;
-
-	padded = g_new0 (guchar, total);
-	padded[1] = 2; /* Block type */
-	fill_random_nonzero (padded + 2, n_pad);
-	memcpy (padded + 3 + n_pad, raw, n_raw); 
-	
-	*n_padded = total;
-	return padded;
-}
-
-guchar* 
-gck_crypto_rsa_unpad_one (guint bits, const guchar *padded, 
-                          gsize n_padded, gsize *n_raw)
-{
-	return unpad_rsa_pkcs1 (0x01, bits, padded, n_padded, n_raw);
-}
-
-guchar* 
-gck_crypto_rsa_unpad_two (guint bits, const guchar *padded, 
-                          gsize n_padded, gsize *n_raw)
-{
-	return unpad_rsa_pkcs1 (0x02, bits, padded, n_padded, n_raw);
+		QUARK (OID_DES_CBC, "1.3.14.3.2.7");
+		QUARK (OID_DES_RC2_CBC, "1.2.840.113549.3.2");
+		QUARK (OID_DES_EDE3_CBC, "1.2.840.113549.3.7");
+		QUARK (OID_DES_RC5_CBC, "1.2.840.113549.3.9");
+		
+		QUARK (OID_PKCS12_PBE_ARCFOUR_SHA1, "1.2.840.113549.1.12.1.1");
+		QUARK (OID_PKCS12_PBE_RC4_40_SHA1, "1.2.840.113549.1.12.1.2");
+		QUARK (OID_PKCS12_PBE_3DES_SHA1, "1.2.840.113549.1.12.1.3");
+		QUARK (OID_PKCS12_PBE_2DES_SHA1, "1.2.840.113549.1.12.1.4");
+		QUARK (OID_PKCS12_PBE_RC2_128_SHA1, "1.2.840.113549.1.12.1.5");
+		QUARK (OID_PKCS12_PBE_RC2_40_SHA1, "1.2.840.113549.1.12.1.6");
+		
+		#undef QUARK
+		
+		g_once_init_leave (&quarks_inited, 1);
+	}
 }
 
 /* -----------------------------------------------------------------------------
@@ -982,10 +94,10 @@
  */
 
 gboolean
-gck_crypto_symkey_generate_simple (int cipher_algo, int hash_algo, 
-                                   const gchar *password, gssize n_password, 
-                                   const guchar *salt, gsize n_salt, int iterations, 
-                                   guchar **key, guchar **iv)
+egg_symkey_generate_simple (int cipher_algo, int hash_algo, 
+                            const gchar *password, gssize n_password, 
+                            const guchar *salt, gsize n_salt, int iterations, 
+                            guchar **key, guchar **iv)
 {
 	gcry_md_hd_t mdh;
 	gcry_error_t gcry;
@@ -1025,10 +137,10 @@
 	n_digest = gcry_md_get_algo_dlen (hash_algo);
 	g_return_val_if_fail (n_digest > 0, FALSE);
 	
-	digest = gcry_calloc_secure (n_digest, 1);
+	digest = egg_secure_alloc (n_digest);
 	g_return_val_if_fail (digest, FALSE);
 	if (key) {
-		*key = gcry_calloc_secure (needed_key, 1);
+		*key = egg_secure_alloc (needed_key);
 		g_return_val_if_fail (*key, FALSE);
 	}
 	if (iv) 
@@ -1081,16 +193,16 @@
 			break;
 	}
 
-	gcry_free (digest);
+	egg_secure_free (digest);
 	gcry_md_close (mdh);
 	
 	return TRUE;
 }
 
 gboolean
-gck_crypto_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password, 
-                                gssize n_password, const guchar *salt, gsize n_salt, int iterations, 
-                                guchar **key, guchar **iv)
+egg_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password, 
+                         gssize n_password, const guchar *salt, gsize n_salt, int iterations, 
+                         guchar **key, guchar **iv)
 {
 	gcry_md_hd_t mdh;
 	gcry_error_t gcry;
@@ -1139,10 +251,10 @@
 		return FALSE;
 	}
 
-	digest = gcry_calloc_secure (n_digest, 1);
+	digest = egg_secure_alloc (n_digest);
 	g_return_val_if_fail (digest, FALSE);
 	if (key) {
-		*key = gcry_calloc_secure (needed_key, 1);
+		*key = egg_secure_alloc (needed_key);
 		g_return_val_if_fail (*key, FALSE);
 	}
 	if (iv) 
@@ -1172,7 +284,7 @@
 		memcpy (*iv, digest + (16 - needed_iv), needed_iv);
 	}
 		
-	gcry_free (digest);
+	egg_secure_free (digest);
 	gcry_md_close (mdh);
 	
 	return TRUE;	
@@ -1213,9 +325,9 @@
 	}
 
 	/* Reqisition me a buffer */
-	hash = gcry_calloc_secure (n_hash, 1);
-	buf_i = gcry_calloc_secure (1, 128);
-	buf_b = gcry_calloc_secure (1, 64);
+	hash = egg_secure_alloc (n_hash);
+	buf_i = egg_secure_alloc (128);
+	buf_b = egg_secure_alloc (64);
 	g_return_val_if_fail (hash && buf_i && buf_b, FALSE);
 		
 	/* Bring in the salt */
@@ -1298,9 +410,9 @@
 		}
 	}  
 	
-	gcry_free (buf_i);
-	gcry_free (buf_b);
-	gcry_free (hash);
+	egg_secure_free (buf_i);
+	egg_secure_free (buf_b);
+	egg_secure_free (hash);
 	gcry_mpi_release (num_b1);
 	gcry_md_close (mdh);
 	
@@ -1308,9 +420,9 @@
 }
 
 gboolean
-gck_crypto_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password, 
-                                   gssize n_password, const guchar *salt, gsize n_salt,
-                                   int iterations, guchar **key, guchar **iv)
+egg_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password, 
+                            gssize n_password, const guchar *salt, gsize n_salt,
+                            int iterations, guchar **key, guchar **iv)
 {
 	gsize n_block, n_key;
 	gboolean ret = TRUE;
@@ -1334,7 +446,7 @@
 	
 	/* Generate us an key */
 	if (key) {
-		*key = gcry_calloc_secure (n_key, 1);
+		*key = egg_secure_alloc (n_key);
 		g_return_val_if_fail (*key != NULL, FALSE);
 		ret = generate_pkcs12 (hash_algo, 1, password, n_password, salt, n_salt, 
 		                       iterations, *key, n_key);
@@ -1354,7 +466,7 @@
 	/* Cleanup in case of failure */
 	if (!ret) {
 		g_free (iv ? *iv : NULL);
-		gcry_free (key ? *key : NULL);
+		egg_secure_free (key ? *key : NULL);
 	}
 	
 	return ret;
@@ -1387,10 +499,10 @@
 	}
 
 	/* Get us a temporary buffers */
-	T = gcry_calloc_secure (n_hash, 1);
-	U = gcry_calloc_secure (n_hash, 1);
+	T = egg_secure_alloc (n_hash);
+	U = egg_secure_alloc (n_hash);
 	n_buf = n_salt + 4;
-	buf = gcry_calloc_secure (n_buf, 1);
+	buf = egg_secure_alloc (n_buf);
 	g_return_val_if_fail (buf && T && U, FALSE);
 
 	/* n_hash blocks in output, rounding up */
@@ -1431,18 +543,18 @@
 		memcpy (output + (i - 1) * n_hash, T, i == l ? r : n_hash);
 	}
 	
-	gcry_free (T);
-	gcry_free (U);
-	gcry_free (buf);
+	egg_secure_free (T);
+	egg_secure_free (U);
+	egg_secure_free (buf);
 	gcry_md_close (mdh);
 	return TRUE;
 }
 
 gboolean
-gck_crypto_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo, 
-                                   const gchar *password, gssize n_password, 
-                                   const guchar *salt, gsize n_salt, int iterations, 
-                                   guchar **key, guchar **iv)
+egg_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo, 
+                            const gchar *password, gssize n_password, 
+                            const guchar *salt, gsize n_salt, int iterations, 
+                            guchar **key, guchar **iv)
 {
 	gsize n_key, n_block;
 	gboolean ret = TRUE;
@@ -1466,7 +578,7 @@
 	
 	/* Generate us an key */
 	if (key) {
-		*key = gcry_calloc_secure (n_key, 1);
+		*key = egg_secure_alloc (n_key);
 		g_return_val_if_fail (*key != NULL, FALSE);
 		ret = generate_pbkdf2 (hash_algo, password, n_password, salt, n_salt, 
 		                       iterations, *key, n_key);
@@ -1485,100 +597,431 @@
 	/* Cleanup in case of failure */
 	if (!ret) {
 		g_free (iv ? *iv : NULL);
-		gcry_free (key ? *key : NULL);
+		egg_secure_free (key ? *key : NULL);
 	}
 	
 	return ret;
 }
 
-/* --------------------------------------------------------------------------
- * INITIALIZATION
+/* ----------------------------------------------------------------------------
+ * DER encoded cipher params
  */
 
-static void
-log_handler (gpointer unused, int unknown, const gchar *msg, va_list va)
-{
-	/* TODO: Figure out additional arguments */
-	g_logv ("gcrypt", G_LOG_LEVEL_MESSAGE, msg, va);
-}
 
-static int 
-no_mem_handler (gpointer unused, size_t sz, unsigned int unknown)
+static gboolean
+read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo, 
+                       const gchar *password, gsize n_password, const guchar *data, 
+                       gsize n_data, gcry_cipher_hd_t *cih)
 {
-	/* TODO: Figure out additional arguments */
-	g_error ("couldn't allocate %lu bytes of memory", 
-	         (unsigned long int)sz);
-	return 0;
-}
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_error_t gcry;
+	const guchar *salt;
+	gsize n_salt;
+	gsize n_block, n_key;
+	guint iterations;
+	guchar *key = NULL;
+	guchar *iv = NULL;
+	gboolean ret;
+
+	g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
+	g_return_val_if_fail (cih != NULL, FALSE);
+	g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+
+	*cih = NULL;
+	ret = FALSE;
+	
+	/* Check if we can use this algorithm */
+	if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0 ||
+	    gcry_md_test_algo (hash_algo) != 0)
+		goto done;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-5-PBE-params", data, n_data);
+	if (!asn) 
+		goto done;
+		
+	salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
+	if (!salt)
+		goto done;
+	if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
+		iterations = 1;
+		
+	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
+	g_return_val_if_fail (n_key > 0, FALSE);
+	n_block = gcry_cipher_get_algo_blklen (cipher_algo);
+		
+	if (!egg_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password, salt,
+	                              n_salt, iterations, &key, n_block > 1 ? &iv : NULL))
+		goto done;
+		
+	gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
+	if (gcry != 0) {
+		g_warning ("couldn't create cipher: %s", gcry_strerror (gcry));
+		goto done;
+	}
+	
+	if (iv) 
+		gcry_cipher_setiv (*cih, iv, n_block);
+	gcry_cipher_setkey (*cih, key, n_key);
+	
+	ret = TRUE;
 
-static void
-fatal_handler (gpointer unused, int unknown, const gchar *msg)
-{
-	/* TODO: Figure out additional arguments */
-	g_log ("gcrypt", G_LOG_LEVEL_ERROR, "%s", msg);
+done:
+	g_free (iv);
+	egg_secure_free (key);
+	
+	if (asn)
+		asn1_delete_structure (&asn);
+		
+	return ret;
 }
 
-static int
-glib_thread_mutex_init (void **lock)
+static gboolean
+setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
 {
-	*lock = g_mutex_new ();
-	return 0;
-}
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_error_t gcry;
+	const guchar *iv;
+	gsize n_iv;
+	guint version;
+	
+	g_assert (data);
 
-static int 
-glib_thread_mutex_destroy (void **lock)
-{
-	g_mutex_free (*lock);
-	return 0;
+	asn = egg_asn1_decode ("PKIX1.pkcs-5-rc2-CBC-params", data, n_data);
+	if (!asn) 
+		return FALSE;
+		
+	if (!egg_asn1_read_uint (asn, "rc2ParameterVersion", &version))
+		return FALSE;
+	
+	iv = egg_asn1_read_content (asn, data, n_data, "iv", &n_iv);
+	asn1_delete_structure (&asn);
+
+	if (!iv)
+		return FALSE;
+		
+	gcry = gcry_cipher_setiv (cih, iv, n_iv);
+			
+	if (gcry != 0) {
+		g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
+		return FALSE;
+	}
+	
+	return TRUE;
 }
 
-static int 
-glib_thread_mutex_lock (void **lock)
+static gboolean
+setup_pkcs5_des_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
 {
-	g_mutex_lock (*lock);
-	return 0;
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_error_t gcry;
+	const guchar *iv;
+	gsize n_iv;
+	
+	g_assert (data);
+
+	asn = egg_asn1_decode ("PKIX1.pkcs-5-des-EDE3-CBC-params", data, n_data);
+	if (!asn)
+		asn = egg_asn1_decode ("PKIX1.pkcs-5-des-CBC-params", data, n_data);
+	if (!asn) 
+		return FALSE;
+	
+	iv = egg_asn1_read_content (asn, data, n_data, "", &n_iv);
+	asn1_delete_structure (&asn);
+
+	if (!iv)
+		return FALSE;
+		
+	gcry = gcry_cipher_setiv (cih, iv, n_iv);
+			
+	if (gcry != 0) {
+		g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
+		return FALSE;
+	}
+	
+	return TRUE;
 }
 
-static int 
-glib_thread_mutex_unlock (void **lock)
+static gboolean
+setup_pkcs5_pbkdf2_params (const gchar *password, gsize n_password, const guchar *data, 
+                           gsize n_data, int cipher_algo, gcry_cipher_hd_t cih)
 {
-	g_mutex_unlock (*lock);
-	return 0;
-}
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gboolean ret;
+	gcry_error_t gcry;
+	guchar *key = NULL; 
+	const guchar *salt;
+	gsize n_salt, n_key;
+	guint iterations;
+	
+	g_assert (cipher_algo);
+	g_assert (data);
+	
+	ret = FALSE;
 
-static struct gcry_thread_cbs glib_thread_cbs = {
-	GCRY_THREAD_OPTION_USER, NULL,
-	glib_thread_mutex_init, glib_thread_mutex_destroy,
-	glib_thread_mutex_lock, glib_thread_mutex_unlock,
-	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 
-};
+	asn = egg_asn1_decode ("PKIX1.pkcs-5-PBKDF2-params", data, n_data);
+	if (!asn)
+		goto done;
+		
+	if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
+		iterations = 1;
+	salt = egg_asn1_read_content (asn, data, n_data, "salt.specified", &n_salt);
+	if (!salt)
+		goto done;
+				
+	if (!egg_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password, 
+	                                 salt, n_salt, iterations, &key, NULL))
+		goto done;
+
+	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
+	g_return_val_if_fail (n_key > 0, FALSE);
+	
+	gcry = gcry_cipher_setkey (cih, key, n_key);
+	if (gcry != 0) {
+		g_message ("couldn't set %lu byte key on cipher", (gulong)n_key);
+		goto done;
+	}
+	
+	ret = TRUE;
+	                                         
+done:
+	egg_secure_free (key);
+	if (asn)
+		asn1_delete_structure (&asn);
+	return ret;
+}
 
-void
-gck_crypto_initialize (void)
+static gboolean
+read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *data, 
+                         gsize n_data, gcry_cipher_hd_t *cih)
 {
-	static gsize gcrypt_initialized = FALSE;
-	unsigned seed;
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gboolean r, ret;
+	GQuark key_deriv_algo, enc_oid;
+	gcry_error_t gcry;
+	int algo, mode;
+	int beg, end;
 
-	if (g_once_init_enter (&gcrypt_initialized)) {
+	g_return_val_if_fail (cih != NULL, FALSE);
+	g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+	
+	init_quarks ();
+	
+	*cih = NULL;
+	ret = FALSE;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-5-PBES2-params", data, n_data);
+	if (!asn)
+		goto done;
 		
-		/* Only initialize libgcrypt if it hasn't already been initialized */
-		if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
-			gcry_control (GCRYCTL_SET_THREAD_CBS, &glib_thread_cbs);
-			gcry_check_version (LIBGCRYPT_VERSION);
-			gcry_set_log_handler (log_handler, NULL);
-			gcry_set_outofcore_handler (no_mem_handler, NULL);
-			gcry_set_fatalerror_handler (fatal_handler, NULL);
-			gcry_set_allocation_handler ((gcry_handler_alloc_t)g_malloc, 
-			                             (gcry_handler_alloc_t)egg_secure_alloc, 
-			                             egg_secure_check, 
-			                             (gcry_handler_realloc_t)egg_secure_realloc, 
-			                             egg_secure_free);
-			gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-		}
+	algo = mode = 0;
+	
+	/* Read in all the encryption type */
+	enc_oid = egg_asn1_read_oid (asn, "encryptionScheme.algorithm");
+	if (!enc_oid)
+		goto done;	
+	if (enc_oid == OID_DES_EDE3_CBC)
+		algo = GCRY_CIPHER_3DES;
+	else if (enc_oid == OID_DES_CBC)
+		algo = GCRY_CIPHER_DES;
+	else if (enc_oid == OID_DES_RC2_CBC)
+		algo = GCRY_CIPHER_RFC2268_128;
+	else if (enc_oid == OID_DES_RC5_CBC)
+		/* RC5 doesn't exist in libgcrypt */;
+	
+	/* Unsupported? */
+	if (algo == 0 || gcry_cipher_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
+		goto done;
+
+	/* Instantiate our cipher */
+	gcry = gcry_cipher_open (cih, algo, GCRY_CIPHER_MODE_CBC, 0);
+	if (gcry != 0) {
+		g_warning ("couldn't create cipher: %s", gcry_cipher_algo_name (algo));
+		goto done;
+	}
 		
-		gcry_create_nonce (&seed, sizeof (seed));
-		srand (seed);
+	/* Read out the parameters */
+	if (asn1_der_decoding_startEnd (asn, data, n_data, "encryptionScheme.parameters",
+	                                &beg, &end) != ASN1_SUCCESS)
+		goto done;
+		
+	switch (algo) {
+	case GCRY_CIPHER_3DES:
+	case GCRY_CIPHER_DES:
+		r = setup_pkcs5_des_params (data + beg, end - beg + 1, *cih);
+		break;
+	case GCRY_CIPHER_RFC2268_128:
+		r = setup_pkcs5_rc2_params (data + beg, end - beg + 1, *cih);
+		break;
+	default:
+		/* Should have been caught on the oid check above */
+		g_assert_not_reached ();
+		r = FALSE;
+		break;
+	};
+
+	if (r != TRUE) 
+		goto done;
+
+	/* Read out the key creation paramaters */
+	key_deriv_algo = egg_asn1_read_oid (asn, "keyDerivationFunc.algorithm");
+	if (!key_deriv_algo)
+		goto done;
+	if (key_deriv_algo != OID_PBKDF2) {
+		g_message ("unsupported key derivation algorithm: %s", g_quark_to_string (key_deriv_algo));
+		goto done;
+	}
+
+	if (asn1_der_decoding_startEnd (asn, data, n_data, "keyDerivationFunc.parameters",
+	                                &beg, &end) != ASN1_SUCCESS)
+		goto done;
+	
+	ret = setup_pkcs5_pbkdf2_params (password, n_password, data + beg, end - beg + 1, algo, *cih);
+
+done:
+	if (ret != TRUE && *cih) {
+		gcry_cipher_close (*cih);
+		*cih = NULL;
+	}
+	
+	if (asn)
+		asn1_delete_structure (&asn);
+	
+	return ret;
+}
+
+static gboolean
+read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password, 
+                        gsize n_password, const guchar *data, gsize n_data, 
+                        gcry_cipher_hd_t *cih)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_error_t gcry;
+	gboolean ret;
+	const guchar *salt;
+	gsize n_salt;
+	gsize n_block, n_key;
+	guint iterations;
+	guchar *key = NULL;
+	guchar *iv = NULL;
+	
+	g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, FALSE);
+	g_return_val_if_fail (cih != NULL, FALSE);
+	g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+	
+	*cih = NULL;
+	ret = FALSE;
+	
+	/* Check if we can use this algorithm */
+	if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
+		goto done;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-12-PbeParams", data, n_data);
+	if (!asn)
+		goto done;
+
+	salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
+	if (!salt)
+		goto done;
+	if (!egg_asn1_read_uint (asn, "iterations", &iterations))
+		goto done;
+	
+	n_block = gcry_cipher_get_algo_blklen (cipher_algo);
+	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
+	
+	/* Generate IV and key using salt read above */
+	if (!egg_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password, 
+	                                        n_password, salt, n_salt, iterations, &key, 
+	                                        n_block > 1 ? &iv : NULL))
+		goto done;
 		
-		g_once_init_leave (&gcrypt_initialized, 1);
+	gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
+	if (gcry != 0) {
+		g_warning ("couldn't create encryption cipher: %s", gcry_strerror (gcry));
+		goto done;
 	}
+	
+	if (iv) 
+		gcry_cipher_setiv (*cih, iv, n_block);
+	gcry_cipher_setkey (*cih, key, n_key);
+	
+	ret = TRUE;
+	
+done:
+	if (ret != TRUE && *cih) {
+		gcry_cipher_close (*cih);
+		*cih = NULL;
+	}
+	
+	g_free (iv);
+	egg_secure_free (key);
+	
+	if (asn)
+		asn1_delete_structure (&asn);
+	
+	return ret;
+}
+
+gboolean
+egg_symkey_read_cipher (GQuark oid_scheme, const gchar *password, gsize n_password,
+                        const guchar *data, gsize n_data, gcry_cipher_hd_t *cih)
+{
+	gboolean ret = FALSE;
+	
+	g_return_val_if_fail (oid_scheme != 0, FALSE);
+	g_return_val_if_fail (cih != NULL, FALSE);
+	g_return_val_if_fail (data != NULL && n_data != 0, FALSE);
+	
+	init_quarks ();
+	
+	/* PKCS#5 PBE */
+	if (oid_scheme == OID_PBE_MD2_DES_CBC)
+		ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+		                             GCRY_MD_MD2, password, n_password, data, n_data, cih);
+
+	else if (oid_scheme == OID_PBE_MD2_RC2_CBC)
+		/* RC2-64 has no implementation in libgcrypt */;
+
+	else if (oid_scheme == OID_PBE_MD5_DES_CBC)
+		ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+		                             GCRY_MD_MD5, password, n_password, data, n_data, cih);
+	else if (oid_scheme == OID_PBE_MD5_RC2_CBC)
+		/* RC2-64 has no implementation in libgcrypt */;
+
+	else if (oid_scheme == OID_PBE_SHA1_DES_CBC)
+		ret = read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+		                             GCRY_MD_SHA1, password, n_password, data, n_data, cih);
+	else if (oid_scheme == OID_PBE_SHA1_RC2_CBC)
+		/* RC2-64 has no implementation in libgcrypt */;
+
+	
+	/* PKCS#5 PBES2 */
+	else if (oid_scheme == OID_PBES2)
+		ret = read_cipher_pkcs5_pbes2 (password, n_password, data, n_data, cih);
+
+		
+	/* PKCS#12 PBE */
+	else if (oid_scheme == OID_PKCS12_PBE_ARCFOUR_SHA1)
+		ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 
+		                              password, n_password, data, n_data, cih);
+	else if (oid_scheme == OID_PKCS12_PBE_RC4_40_SHA1)
+		/* RC4-40 has no implementation in libgcrypt */;
+
+	else if (oid_scheme == OID_PKCS12_PBE_3DES_SHA1)
+		ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 
+		                              password, n_password, data, n_data, cih);
+	else if (oid_scheme == OID_PKCS12_PBE_2DES_SHA1) 
+		/* 2DES has no implementation in libgcrypt */;
+		
+	else if (oid_scheme == OID_PKCS12_PBE_RC2_128_SHA1)
+		ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC, 
+		                              password, n_password, data, n_data, cih);
+
+	else if (oid_scheme == OID_PKCS12_PBE_RC2_40_SHA1)
+		ret = read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC, 
+		                              password, n_password, data, n_data, cih);
+
+	if (ret == FALSE)
+    		g_message ("unsupported or invalid cipher: %s", g_quark_to_string (oid_scheme));
+	
+    	return ret;
 }

Copied: trunk/egg/egg-symkey.h (from r1460, /trunk/pkcs11/gck/gck-crypto.h)
==============================================================================
--- /trunk/pkcs11/gck/gck-crypto.h	(original)
+++ trunk/egg/egg-symkey.h	Sun Jan 18 22:24:09 2009
@@ -19,184 +19,58 @@
  * 02111-1307, USA.  
  */
 
-#ifndef GCKCRYPTO_H_
-#define GCKCRYPTO_H_
+#ifndef EGG_SYMKEY_H_
+#define EGG_SYMKEY_H_
 
 #include <glib.h>
 
 #include <gcrypt.h>
 
-#include "pkcs11/pkcs11.h"
+gboolean                 egg_symkey_generate_simple             (int cipher_algo, 
+                                                                 int hash_algo, 
+                                                                 const gchar *password, 
+                                                                 gssize n_password,
+                                                                 const guchar *salt, 
+                                                                 gsize n_salt, 
+                                                                 int iterations, 
+                                                                 guchar **key, 
+                                                                 guchar **iv);
+
+gboolean                 egg_symkey_generate_pbe                (int cipher_algo, 
+                                                                 int hash_algo, 
+                                                                 const gchar *password,
+                                                                 gssize n_password,
+                                                                 const guchar *salt, 
+                                                                 gsize n_salt, 
+                                                                 int iterations, 
+                                                                 guchar **key, 
+                                                                 guchar **iv);
+
+gboolean                 egg_symkey_generate_pkcs12             (int cipher_algo, 
+                                                                 int hash_algo, 
+                                                                 const gchar *password,
+                                                                 gssize n_password,
+                                                                 const guchar *salt, 
+                                                                 gsize n_salt,
+                                                                 int iterations, 
+                                                                 guchar **key, 
+                                                                 guchar **iv);
+
+gboolean                 egg_symkey_generate_pbkdf2             (int cipher_algo, 
+                                                                 int hash_algo, 
+                                                                 const gchar *password,
+                                                                 gssize n_password,
+                                                                 const guchar *salt, 
+                                                                 gsize n_salt, 
+                                                                 int iterations, 
+                                                                 guchar **key, 
+                                                                 guchar **iv);
+
+gboolean                 egg_symkey_read_cipher                 (GQuark oid_scheme, 
+                                                                 const gchar *password,
+                                                                 gsize n_password, 
+                                                                 const guchar *data, 
+                                                                 gsize n_data, 
+                                                                 gcry_cipher_hd_t *cih);
 
-typedef guchar* (*GckCryptoPadding) (guint n_modulus, const guchar* raw, 
-                                     gsize n_raw, gsize *n_padded);
-
-static const CK_MECHANISM_TYPE GCK_CRYPTO_RSA_MECHANISMS[] = {
-	CKM_RSA_PKCS,
-	CKM_RSA_X_509
-};
-
-static const CK_MECHANISM_TYPE GCK_CRYPTO_DSA_MECHANISMS[] = {
-	CKM_DSA
-};
-
-void                     gck_crypto_initialize                         (void);
-
-CK_RV                    gck_crypto_perform                            (gcry_sexp_t sexp, 
-                                                                        CK_MECHANISM_TYPE mech, 
-                                                                        CK_ATTRIBUTE_TYPE method, 
-                                                                        CK_BYTE_PTR bufone, 
-                                                                        CK_ULONG n_bufone, 
-                                                                        CK_BYTE_PTR buftwo, 
-                                                                        CK_ULONG_PTR n_buftwo);
-
-CK_RV                    gck_crypto_encrypt                            (gcry_sexp_t sexp, 
-                                                                        CK_MECHANISM_TYPE mech, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR encrypted, 
-                                                                        CK_ULONG_PTR n_encrypted);
-
-CK_RV                    gck_crypto_encrypt_rsa                        (gcry_sexp_t sexp, 
-                                                                        GckCryptoPadding padding, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR encrypted, 
-                                                                        CK_ULONG_PTR n_encrypted);
-
-
-CK_RV                    gck_crypto_decrypt                            (gcry_sexp_t sexp, 
-                                                                        CK_MECHANISM_TYPE mech, 
-                                                                        CK_BYTE_PTR encrypted, 
-                                                                        CK_ULONG n_encrypted, 
-									CK_BYTE_PTR data, 
-									CK_ULONG_PTR n_data);
-
-CK_RV                    gck_crypto_decrypt_rsa                        (gcry_sexp_t sexp, 
-                                                                        GckCryptoPadding padding, 
-                                                                        CK_BYTE_PTR encrypted, 
-                                                                        CK_ULONG n_encrypted, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG_PTR n_data);
-
-CK_RV                    gck_crypto_sign                               (gcry_sexp_t sexp, 
-                                                                        CK_MECHANISM_TYPE mech, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
-                                                                        CK_ULONG_PTR n_signature);
-
-CK_RV                    gck_crypto_sign_rsa                           (gcry_sexp_t sexp, 
-                                                                        GckCryptoPadding padding, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
-                                                                        CK_ULONG_PTR n_signature);
-
-CK_RV                    gck_crypto_sign_dsa                           (gcry_sexp_t sexp, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
-                                                                        CK_ULONG_PTR n_signature);
-
-CK_RV                    gck_crypto_verify                             (gcry_sexp_t sexp, 
-                                                                        CK_MECHANISM_TYPE mech, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
-                                                                        CK_ULONG n_signature);
-
-CK_RV                    gck_crypto_verify_rsa                         (gcry_sexp_t sexp, 
-                                                                        GckCryptoPadding padding, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
-                                                                        CK_ULONG n_signature);
-
-
-CK_RV                    gck_crypto_verify_dsa                         (gcry_sexp_t sexp, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
-                                                                        CK_ULONG n_signature);
-
-gboolean                 gck_crypto_sexp_parse_key                     (gcry_sexp_t sexp,
-                                                                        int *algorithm, 
-                                                                        gboolean *is_private, 
-                                                                        gcry_sexp_t *numbers);
-
-gboolean                 gck_crypto_sexp_key_to_public                 (gcry_sexp_t sexp, 
-                                                                        gcry_sexp_t *pub);
-
-gboolean                 gck_crypto_sexp_extract_mpi                   (gcry_sexp_t sexp, 
-                                                                        gcry_mpi_t *mpi, 
-                                                                        ...) G_GNUC_NULL_TERMINATED;
-
-void                     gck_crypto_sexp_dump                          (gcry_sexp_t sexp);
-
-guchar*	                 gck_crypto_rsa_pad_raw                        (guint bits, 
-       	                                                                const guchar* raw,
-       	                                                                gsize n_raw, 
-       	                                                                gsize *n_padded);
-
-guchar*                  gck_crypto_rsa_pad_one                        (guint bits, 
-                                                                        const guchar* raw, 
-                                                                        gsize n_raw, 
-                                                                        gsize *n_padded);
-
-guchar*                  gck_crypto_rsa_pad_two                        (guint bits, 
-                                                                        const guchar* raw, 
-                                                                        gsize n_raw, 
-                                                                        gsize *n_padded);
-
-guchar*                  gck_crypto_rsa_unpad_one                      (guint bits, 
-                                                                        const guchar *padded, 
-                                                                        gsize n_padded, 
-                                                                        gsize *n_raw);
-
-guchar*                  gck_crypto_rsa_unpad_two                      (guint bits, 
-                                                                        const guchar* padded, 
-                                                                        gsize n_padded, 
-                                                                        gsize *n_raw);
-
-gboolean                 gck_crypto_symkey_generate_simple             (int cipher_algo, 
-                                                                        int hash_algo, 
-                                                                        const gchar *password, 
-                                                                        gssize n_password,
-                                                                        const guchar *salt, 
-                                                                        gsize n_salt, 
-                                                                        int iterations, 
-                                                                        guchar **key, 
-                                                                        guchar **iv);
-
-gboolean                 gck_crypto_symkey_generate_pbe                (int cipher_algo, 
-                                                                        int hash_algo, 
-                                                                        const gchar *password,
-                                                                        gssize n_password,
-                                                                        const guchar *salt, 
-                                                                        gsize n_salt, 
-                                                                        int iterations, 
-                                                                        guchar **key, 
-                                                                        guchar **iv);
-
-gboolean                 gck_crypto_symkey_generate_pkcs12             (int cipher_algo, 
-                                                                        int hash_algo, 
-                                                                        const gchar *password,
-                                                                        gssize n_password,
-                                                                        const guchar *salt, 
-                                                                        gsize n_salt,
-                                                                        int iterations, 
-									guchar **key, 
-									guchar **iv);
-
-gboolean                 gck_crypto_symkey_generate_pbkdf2             (int cipher_algo, 
-                                                                        int hash_algo, 
-                                                                        const gchar *password,
-                                                                        gssize n_password,
-                                                                        const guchar *salt, 
-                                                                        gsize n_salt, 
-                                                                        int iterations, 
-                                                                        guchar **key, 
-                                                                        guchar **iv);
-
-#endif /* GCKCRYPTO_H_ */
+#endif /* EGG_SYMKEY_H_ */

Modified: trunk/egg/tests/Makefile.am
==============================================================================
--- trunk/egg/tests/Makefile.am	(original)
+++ trunk/egg/tests/Makefile.am	Sun Jan 18 22:24:09 2009
@@ -8,7 +8,10 @@
 # Test files should be listed in order they need to run
 UNIT_AUTO = \
 	unit-test-asn1.c \
+	unit-test-hex.c \
 	unit-test-secmem.c \
+	unit-test-symkey.c \
+	unit-test-openssl.c \
 	$(BUILT_SOURCES)
 
 UNIT_PROMPT = 

Modified: trunk/egg/tests/unit-test-asn1.c
==============================================================================
--- trunk/egg/tests/unit-test-asn1.c	(original)
+++ trunk/egg/tests/unit-test-asn1.c	Sun Jan 18 22:24:09 2009
@@ -274,11 +274,6 @@
 	oid = egg_asn1_read_oid (asn, "nonExistant");
 	g_assert (oid == 0);
 
-	/* No quark of this has been defined, so should return an invalid OID */
-	oid = egg_asn1_read_oid (asn, "data");
-	g_assert (oid != 0);
-	g_assert_cmpstr (g_quark_to_string (oid), !=, "SOME DATA");
-	
 	/* Now a quark has been defined */
 	check = g_quark_from_static_string ("SOME DATA");
 	oid = egg_asn1_read_oid (asn, "data");

Copied: trunk/egg/tests/unit-test-hex.c (from r1460, /trunk/pkcs11/gck/tests/unit-test-util.c)
==============================================================================
--- /trunk/pkcs11/gck/tests/unit-test-util.c	(original)
+++ trunk/egg/tests/unit-test-hex.c	Sun Jan 18 22:24:09 2009
@@ -27,7 +27,7 @@
 
 #include "run-auto-test.h"
 
-#include "gck/gck-util.h"
+#include "egg-hex.h"
 
 static const guchar TEST_DATA[] = { 0x05, 0xD6, 0x95, 0x96, 0x10, 0x12, 0xAE, 0x35 };
 static const gchar *TEST_HEX = "05D695961012AE35";
@@ -37,7 +37,7 @@
 {
 	gchar *hex;
 	
-	hex = gck_util_hex_encode (TEST_DATA, sizeof (TEST_DATA));
+	hex = egg_hex_encode (TEST_DATA, sizeof (TEST_DATA));
 	g_assert (hex);
 	g_assert_cmpstr (hex, ==, TEST_HEX);
 }
@@ -47,23 +47,23 @@
 	guchar *data;
 	gsize n_data;
 	
-	data = gck_util_hex_decode (TEST_HEX, -1, &n_data);
+	data = egg_hex_decode (TEST_HEX, -1, &n_data);
 	g_assert (data);
 	g_assert (n_data == sizeof (TEST_DATA));
 	g_assert (memcmp (data, TEST_DATA, n_data) == 0);
 
 	/* Spaces should be ignored */
-	data = gck_util_hex_decode (TEST_HEX_SPACE, -1, &n_data);
+	data = egg_hex_decode (TEST_HEX_SPACE, -1, &n_data);
 	g_assert (data);
 	g_assert (n_data == sizeof (TEST_DATA));
 	g_assert (memcmp (data, TEST_DATA, n_data) == 0);
 
 	/* Invalid input, null out */
-	data = gck_util_hex_decode ("AB", 1, &n_data);
+	data = egg_hex_decode ("AB", 1, &n_data);
 	g_assert (!data);
 
 	/* Nothing in, empty out */
-	data = gck_util_hex_decode ("AB", 0, &n_data);
+	data = egg_hex_decode ("AB", 0, &n_data);
 	g_assert (data);
 	g_assert (n_data == 0);
 }

Copied: trunk/egg/tests/unit-test-openssl.c (from r1460, /trunk/pkcs11/gck/tests/unit-test-data-openssl.c)
==============================================================================
--- /trunk/pkcs11/gck/tests/unit-test-data-openssl.c	(original)
+++ trunk/egg/tests/unit-test-openssl.c	Sun Jan 18 22:24:09 2009
@@ -25,9 +25,8 @@
 
 #include "run-auto-test.h"
 
-#include "gck/gck-crypto.h"
-#include "gck/gck-data-pem.h"
-#include "gck/gck-data-openssl.h"
+#include "egg-symkey.h"
+#include "egg-openssl.h"
 
 #include <glib.h>
 
@@ -51,7 +50,7 @@
 parse_reference (GQuark type, const guchar *data, gsize n_data,
                  GHashTable *headers, gpointer user_data)
 {
-	GckDataResult res;
+	gboolean res;
 	const gchar *dekinfo;
 	
 	g_assert ("no data in PEM callback" && data != NULL);
@@ -60,13 +59,13 @@
 	n_refenc = n_data;
 	
 	g_assert ("no headers present in file" && headers != NULL);
-	refheaders = gck_data_pem_headers_new ();
+	refheaders = egg_openssl_headers_new ();
 	g_hash_table_foreach (headers, copy_each_key_value, refheaders);
-	dekinfo = gck_data_openssl_get_dekinfo (headers);
+	dekinfo = egg_openssl_get_dekinfo (headers);
 	g_assert ("no dekinfo in headers" && dekinfo != NULL);
 	
-	res = gck_data_openssl_decrypt_block (dekinfo, "booo", 4, data, n_data, &refdata, &n_refdata);
-	g_assert ("couldn't openssl decrypt block" && res == GCK_DATA_SUCCESS);
+	res = egg_openssl_decrypt_block (dekinfo, "booo", 4, data, n_data, &refdata, &n_refdata);
+	g_assert ("couldn't openssl decrypt block" && res == TRUE);
 	g_assert ("no data returned from openssl decrypt" && refdata != NULL);
 	g_assert ("invalid amount of data returned from openssl decrypt" && n_refdata == n_data);
 }
@@ -79,7 +78,7 @@
 	
 	input = test_read_testdata ("pem-rsa-enc.key", &n_input);
 
-	num = gck_data_pem_parse (input, n_input, parse_reference, NULL);
+	num = egg_openssl_pem_parse (input, n_input, parse_reference, NULL);
 	g_assert ("couldn't PEM block in reference data" && num == 1);
 	
 	g_assert ("parse_reference() wasn't called" && refdata != NULL);
@@ -92,10 +91,10 @@
 	gsize n_encrypted;
 	gboolean ret;
 	
-	dekinfo = gck_data_openssl_get_dekinfo (refheaders); 
+	dekinfo = egg_openssl_get_dekinfo (refheaders); 
 	g_assert ("no dekinfo in headers" && dekinfo != NULL);
 
-	ret = gck_data_openssl_encrypt_block (dekinfo, "booo", 4, refdata, n_refdata, &encrypted, &n_encrypted);
+	ret = egg_openssl_encrypt_block (dekinfo, "booo", 4, refdata, n_refdata, &encrypted, &n_encrypted);
 	g_assert ("couldn't openssl encrypt block" && ret == TRUE);
 	g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
 	g_assert ("invalid amount of data returned from openssl encrypt" && n_refdata <= n_encrypted);
@@ -111,21 +110,21 @@
 DEFINE_TEST(openssl_roundtrip)
 {
 	const gchar *dekinfo;
-	GckDataResult res;
+	gboolean res;
 	gboolean ret;
 	guchar *encrypted, *decrypted;
 	gsize n_encrypted, n_decrypted;
 	int i;
 	
-	dekinfo = gck_data_openssl_prep_dekinfo (refheaders);
+	dekinfo = egg_openssl_prep_dekinfo (refheaders);
 	
-	ret = gck_data_openssl_encrypt_block (dekinfo, "password", -1, TEST_DATA, TEST_DATA_L, &encrypted, &n_encrypted);
+	ret = egg_openssl_encrypt_block (dekinfo, "password", -1, TEST_DATA, TEST_DATA_L, &encrypted, &n_encrypted);
 	g_assert ("couldn't openssl encrypt block" && ret == TRUE);
 	g_assert ("no data returned from openssl encrypt" && encrypted != NULL);
 	g_assert ("invalid amount of data returned from openssl encrypt" && TEST_DATA_L <= n_encrypted);
 
-	res = gck_data_openssl_decrypt_block (dekinfo, "password", 8, encrypted, n_encrypted, &decrypted, &n_decrypted);
-	g_assert ("couldn't openssl decrypt block" && res == GCK_DATA_SUCCESS);
+	res = egg_openssl_decrypt_block (dekinfo, "password", 8, encrypted, n_encrypted, &decrypted, &n_decrypted);
+	g_assert ("couldn't openssl decrypt block" && res == TRUE);
 	g_assert ("no data returned from openssl decrypt" && decrypted != NULL);
 
 	/* Check that the data was decrypted properly */

Copied: trunk/egg/tests/unit-test-symkey.c (from r1460, /trunk/pkcs11/gck/tests/unit-test-crypto.c)
==============================================================================
--- /trunk/pkcs11/gck/tests/unit-test-crypto.c	(original)
+++ trunk/egg/tests/unit-test-symkey.c	Sun Jan 18 22:24:09 2009
@@ -27,49 +27,18 @@
 
 #include "run-auto-test.h"
 
-#include "gck/gck-crypto.h"
+#include "egg-symkey.h"
 
 #include <gcrypt.h>
 
-#define TEST_RSA \
-"(private-key (rsa " \
-"(n  #00B78758D55EBFFAB61D07D0DC49B5309A6F1DA2AE51C275DFC2370959BB81AC0C39093B1C618E396161A0DECEB8768D0FFB14F197B96C3DA14190EE0F20D51315#)" \
-"(e #010001#)" \
-"(d #108BCAC5FDD35812981E6EC5957D98E2AB76E4064C47B861D27C2CC322C50792313C852B4164A035B42D261F1A09F9FFE8F477F9F78FF2EABBDA6BA875C671D7#)" \
-"(p #00C357F11B19A18C66573D25D1E466D9AB8BCDDCDFE0B2E80BD46712C4BEC18EB7#)" \
-"(q #00F0843B90A60EF7034CA4BE80414ED9497CABCC685143B388013FF989CBB0E093#)" \
-"(u #12F2555F52EB56329A991CF0404B51C68AC921AD370A797860F550415FF987BD#)" \
-"))"
-
-#define TEST_DSA \
-"(private-key (dsa " \
-"  (p #0090EC0B60735839C754EAF8F64BB03FC35398D69772BFAE540079DEA2D3A61FAFFB27630A038A01A3D0CD62A10745A574A27ECB462F4F0885B79C61BBE954A60A29668AD54BBA5C07A72FD8B1105249670B339DF2C59E64A47064EFCF0B7236C5C72CD55CEB32917430BEC9A003D4E484FBAA84D79571B38D6B5AC95BB73E3F7B#)" \
-"  (q #00FA214A1385C21BFEBAADAB240A2430C607D56271#)" \
-"  (g #2DE05751F5DAEE97F3D43C54595A3E94A080728F0C66C98AEBED5762F6AB155802D8359EAD1DE1EC36A459FBEEEA48E59B9E6A8CB4F5295936B3CC881A5D957C7339175E2CFFE0F30D3711E430DB6648C2EB474AA10A4A3297450531FF2C7C6951220C9D446B6B6B0F00262E1EBEB3CC861476AA518CC555C9ABF9E5F39023FC#)" \
-"  (y #54734451DB79D4EEDF0BBCEBD43BB6CBB7B8584603B957080075DD318EB5B0266D4B20DC5EFF376BDFC4EA2983B1F7F02A39ED4C619ED68712729FFF3B7C696ADD1B6D748F56A4B4BEC5C4385E528423A3B88AE65E6D5500F97839E7A486255982189C3B4FA8D94338C76F0E5CAFC9A30A1ED728BB9F2091D594E3250A09EA00#)" \
-"  (x #00876F84F709D51108DFB0CBFA1F1C569C09C413EC#)))"
-
-gcry_sexp_t rsakey = NULL;
-gcry_sexp_t dsakey = NULL;
-
 DEFINE_SETUP(crypto_setup)
 {
-	gcry_error_t gcry;
-	
-	gck_crypto_initialize ();
-	
-	gcry = gcry_sexp_new (&rsakey, TEST_RSA, strlen (TEST_RSA), 1);
-	g_return_if_fail (gcry == 0);
-	gcry = gcry_sexp_new (&dsakey, TEST_DSA, strlen (TEST_DSA), 1);
-	g_return_if_fail (gcry == 0);
+	gcry_check_version (LIBGCRYPT_VERSION);
 }
 
 DEFINE_TEARDOWN(crypto_setup)
 {
-	gcry_sexp_release (rsakey);
-	rsakey = NULL;
-	gcry_sexp_release (dsakey);
-	dsakey = NULL;
+
 }
 
 const static struct {
@@ -162,7 +131,7 @@
 		if (!all_generation_tests[i].result_simple)
 			continue;
 		
-		ret = gck_crypto_symkey_generate_simple (all_generation_tests[i].cipher_algo, 
+		ret = egg_symkey_generate_simple (all_generation_tests[i].cipher_algo, 
                                                          all_generation_tests[i].hash_algo,
                                                          all_generation_tests[i].password, -1,
                                                          (guchar*)all_generation_tests[i].salt, 8,
@@ -188,7 +157,7 @@
 		if (!all_generation_tests[i].result_pkcs12)
 			continue;
 		
-		ret = gck_crypto_symkey_generate_pkcs12 (all_generation_tests[i].cipher_algo, 
+		ret = egg_symkey_generate_pkcs12 (all_generation_tests[i].cipher_algo, 
                                                          all_generation_tests[i].hash_algo,
                                                          all_generation_tests[i].password, -1,
                                                          (guchar*)all_generation_tests[i].salt, 8,
@@ -214,7 +183,7 @@
 		if (!all_generation_tests[i].result_pbkdf2)
 			continue;
 		
-		ret = gck_crypto_symkey_generate_pbkdf2 (all_generation_tests[i].cipher_algo, 
+		ret = egg_symkey_generate_pbkdf2 (all_generation_tests[i].cipher_algo, 
                                                          all_generation_tests[i].hash_algo,
                                                          all_generation_tests[i].password, -1,
                                                          (guchar*)all_generation_tests[i].salt, 8,
@@ -240,7 +209,7 @@
 		if (!all_generation_tests[i].result_pbe)
 			continue;
 		
-		ret = gck_crypto_symkey_generate_pbe (all_generation_tests[i].cipher_algo, 
+		ret = egg_symkey_generate_pbe (all_generation_tests[i].cipher_algo, 
                                                       all_generation_tests[i].hash_algo,
                                                       all_generation_tests[i].password, -1,
                                                       (guchar*)all_generation_tests[i].salt, 8,
@@ -255,61 +224,3 @@
 			
 	}
 }
-
-DEFINE_TEST(parse_key)
-{
-	gcry_sexp_t sexp = NULL;
-	gcry_mpi_t mpi = NULL;
-	gboolean ret;
-	gboolean is_priv = FALSE;
-	int algorithm = 0;
-	
-	/* Get the private key out */
-	ret = gck_crypto_sexp_parse_key (rsakey, &algorithm, &is_priv, &sexp);
-	g_assert (ret);
-	g_assert (algorithm == GCRY_PK_RSA);
-	g_assert (is_priv == TRUE);
-	g_assert (sexp != NULL);
-	
-	ret = gck_crypto_sexp_extract_mpi (rsakey, &mpi, "p", NULL);
-	g_assert (ret);
-	g_assert (mpi != NULL);
-}
-
-DEFINE_TEST(sexp_key_to_public)
-{
-	gcry_sexp_t pubkey = NULL;
-	guchar id1[20], id2[20];
-	gboolean ret;
-	guchar *p;
-	
-	/* RSA */
-	ret = gck_crypto_sexp_key_to_public (rsakey, &pubkey);
-	g_assert (ret);
-	g_assert (pubkey != NULL);
-	
-	p = gcry_pk_get_keygrip (rsakey, id1);
-	g_return_if_fail (p == id1);
-	p = gcry_pk_get_keygrip (pubkey, id2);
-	g_return_if_fail (p == id2);
-
-	g_assert (memcmp (id1, id2, sizeof (id1)) == 0);
-	
-	gcry_sexp_release (pubkey);
-
-
-	/* DSA */
-	ret = gck_crypto_sexp_key_to_public (dsakey, &pubkey);
-	g_assert (ret);
-	g_assert (pubkey != NULL);
-	
-	p = gcry_pk_get_keygrip (dsakey, id1);
-	g_return_if_fail (p == id1);
-	p = gcry_pk_get_keygrip (pubkey, id2);
-	g_return_if_fail (p == id2);
-
-	g_assert (memcmp (id1, id2, sizeof (id1)) == 0);
-	
-	gcry_sexp_release (pubkey);
-
-}

Added: trunk/gcr/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/gcr/Makefile.am	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,62 @@
+incdir = $(includedir)/gcr
+
+inc_HEADERS = \
+	gcr-parser.h \
+	gcr-types.h
+
+INCLUDES = \
+	-I$(top_builddir) \
+    	-I$(top_srcdir) \
+    	$(GOBJECT_CFLAGS) \
+	$(GLIB_CFLAGS)
+
+BUILT_SOURCES = \
+	gcr-marshal.c gcr-marshal.h
+
+lib_LTLIBRARIES = libgcr.la
+
+libgcr_la_SOURCES = \
+	gcr-internal.c gcr-internal.h \
+	gcr-parser.c gcr-parser.h \
+	gcr-types.h \
+	$(BUILT_SOURCES)
+    
+libgcr_la_LDFLAGS = \
+    	-version-info $(GCR_LT_RELEASE) \
+	-no-undefined -export-symbols-regex 'gcr_*'
+    
+libgcr_la_LIBADD = \
+	$(top_builddir)/egg/libegg.la \
+	$(top_builddir)/gp11/libgp11.la \
+	$(GOBJECT_LIBS) \
+	$(GLIB_LIBS)
+
+gcr-marshal.h: gcr-marshal.list $(GLIB_GENMARSHAL)
+	$(GLIB_GENMARSHAL) $< --header --prefix=_gcr_marshal > $@
+
+gcr-marshal.c: gcr-marshal.list $(GLIB_GENMARSHAL)
+	echo "#include \"gcr-marshal.h\"" > $@ && \
+	$(GLIB_GENMARSHAL) $< --body --prefix=_gcr_marshal >> $@
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = gcr-$(GCR_MAJOR).pc
+
+EXTRA_DIST = \
+	gcr.pc.in \
+	gcr-marshal.list
+    
+DISTCLEANFILES = \
+	gcr-$(GCR_MAJOR).pc
+    
+gcr-$(GCR_MAJOR).pc: gcr.pc
+	cp gcr.pc gcr-$(GCR_MAJOR).pc
+
+if WITH_TESTS
+TESTS_DIR = tests
+else
+TESTS_DIR = 
+endif
+
+SUBDIRS = . \
+	$(TESTS_DIR)
+	
\ No newline at end of file

Added: trunk/gcr/gcr-import-dialog.glade
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-import-dialog.glade	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
+<!--Generated with glade3 3.4.5 on Sat Jan 17 14:53:28 2009 -->
+<glade-interface>
+  <widget class="GtkDialog" id="dialog1">
+    <property name="border_width">5</property>
+    <property name="window_position">GTK_WIN_POS_CENTER_ON_PARENT</property>
+    <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+    <property name="has_separator">False</property>
+    <child internal-child="vbox">
+      <widget class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="spacing">2</property>
+        <child>
+          <widget class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="spacing">6</property>
+            <child>
+              <widget class="GtkHBox" id="hbox2">
+                <property name="visible">True</property>
+                <property name="spacing">12</property>
+                <child>
+                  <widget class="GtkImage" id="image1">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="yalign">1</property>
+                    <property name="stock">gtk-dialog-authentication</property>
+                    <property name="icon_size">6</property>
+                  </widget>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkVBox" id="vbox2">
+                    <property name="visible">True</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <widget class="GtkLabel" id="primary-text">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">&lt;span size='large' weight='bold'&gt;Import Certificates and Keys&lt;/span&gt;</property>
+                        <property name="use_markup">True</property>
+                      </widget>
+                    </child>
+                    <child>
+                      <widget class="GtkLabel" id="secondary-text">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Secondary prompt text</property>
+                      </widget>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </widget>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+              </packing>
+            </child>
+            <child>
+              <widget class="GtkTable" id="table1">
+                <property name="visible">True</property>
+                <property name="n_rows">2</property>
+                <property name="n_columns">2</property>
+                <property name="column_spacing">12</property>
+                <property name="row_spacing">6</property>
+                <child>
+                  <widget class="GtkEntry" id="password-entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkComboBox" id="location-combo">
+                    <property name="visible">True</property>
+                    <property name="button_sensitivity">GTK_SENSITIVITY_ON</property>
+                  </widget>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Password:</property>
+                  </widget>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options">GTK_FILL</property>
+                  </packing>
+                </child>
+                <child>
+                  <widget class="GtkLabel" id="label4">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Import Into:</property>
+                  </widget>
+                  <packing>
+                    <property name="x_options">GTK_FILL</property>
+                    <property name="y_options">GTK_FILL</property>
+                  </packing>
+                </child>
+              </widget>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <widget class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <child>
+              <widget class="GtkButton" id="button1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-cancel</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+            </child>
+            <child>
+              <widget class="GtkButton" id="button2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-ok</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </widget>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">GTK_PACK_END</property>
+          </packing>
+        </child>
+      </widget>
+    </child>
+  </widget>
+</glade-interface>

Added: trunk/gcr/gcr-importer.c
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-importer.c	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,213 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2008 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "config.h"
+
+#include "gcr-importer.h"
+
+enum {
+	PROP_0,
+	PROP_IMPORTER
+};
+
+enum {
+	SIGNAL,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GcrImporter, gcr_importer, G_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL 
+ */
+
+/* -----------------------------------------------------------------------------
+ * OBJECT 
+ */
+
+
+static GObject* 
+gcr_importer_constructor (GType type, guint n_props, GObjectConstructParam *props) 
+{
+	GcrImporter *self = GCR_IMPORTER (G_OBJECT_CLASS (gcr_importer_parent_class)->constructor(type, n_props, props));
+	g_return_val_if_fail (self, NULL);	
+
+
+	
+	return G_OBJECT (self);
+}
+
+static void
+gcr_importer_init (GcrImporter *self)
+{
+
+}
+
+static void
+gcr_importer_dispose (GObject *obj)
+{
+	GcrImporter *self = GCR_IMPORTER (obj);
+    
+	G_OBJECT_CLASS (gcr_importer_parent_class)->dispose (obj);
+}
+
+static void
+gcr_importer_finalize (GObject *obj)
+{
+	GcrImporter *self = GCR_IMPORTER (obj);
+
+	G_OBJECT_CLASS (gcr_importer_parent_class)->finalize (obj);
+}
+
+static void
+gcr_importer_set_property (GObject *obj, guint prop_id, const GValue *value, 
+                           GParamSpec *pspec)
+{
+	GcrImporter *self = GCR_IMPORTER (obj);
+	
+	switch (prop_id) {
+	case PROP_IMPORTER:
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gcr_importer_get_property (GObject *obj, guint prop_id, GValue *value, 
+                           GParamSpec *pspec)
+{
+	GcrImporter *self = GCR_IMPORTER (obj);
+	
+	switch (prop_id) {
+	case PROP_IMPORTER:
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gcr_importer_class_init (GcrImporterClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+    
+	gobject_class->constructor = gcr_importer_constructor;
+	gobject_class->dispose = gcr_importer_dispose;
+	gobject_class->finalize = gcr_importer_finalize;
+	gobject_class->set_property = gcr_importer_set_property;
+	gobject_class->get_property = gcr_importer_get_property;
+    
+	g_object_class_install_property (gobject_class, PROP_IMPORTER,
+	           g_param_spec_pointer ("importer", "Importer", "Importer.", G_PARAM_READWRITE));
+    
+	signals[SIGNAL] = g_signal_new ("signal", GCR_TYPE_IMPORTER, 
+	                                G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrImporterClass, signal),
+	                                NULL, NULL, g_cclosure_marshal_VOID__OBJECT, 
+	                                G_TYPE_NONE, 0);
+	
+	_gcr_initialize ();
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC 
+ */
+
+GcrImporter*
+gcr_importer_new (void)
+{
+	return g_object_new (GCR_TYPE_IMPORTER, NULL);
+}
+
+gboolean
+gcr_importer_import_data (GcrImporter *self, const guchar *data, gsize n_data, 
+                          GError *err)
+{
+	GckParser *parser;
+	gulong parsed_conn;
+	gulong auth_conn;
+	gboolean ret;
+	
+	g_return_val_if_fail (GCR_IS_IMPORTER (self), FALSE);
+	g_return_val_if_fail (data || !n_data, FALSE);
+	g_return_val_if_fail (!error || !*error, FALSE);
+	
+	
+	xxxx;
+	
+	
+	/* 
+	 * Parse to see if it's something that needs a password
+	 *   if we can't prompt, 
+	 *     return an error
+	 * Possibly prompt, if password needed, with all information necessary
+	 *   
+	 */
+	
+	
+	g_object_ref (self);
+	
+	parser = gcr_importer_get_parser (self);
+	
+	/* Listen in to the parser */
+	g_object_ref (parser);
+	parsed_conn = g_signal_connect (parser, "parsed-item", G_CALLBACK (parser_parsed_item), self);
+	auth_conn = g_signal_connect (parser, "authenticate", G_CALLBACK (parser_authenticate), self);
+	
+	/* Feed the parser the data */
+	ret = gcr_parser_parse_data (parser, data, n_data, err);
+	
+	/* Now we should have all the data ready, check if we should prompt... */
+	/* Import data one by one into module */
+	
+	g_signal_handler_disconnect (parser, parsed_conn);
+	g_signal_handler_disconnect (parser, auth_conn);
+	g_object_unref (parser);
+	
+	g_object_unref (self);
+	
+	return ret;
+}
+
+gboolean
+gcr_importer_import_file (GcrImporter *self, const gchar *filename, 
+                          GError *err)
+{
+	gboolean ret;
+	gchar *data;
+	gsize n_data;
+	
+	g_return_val_if_fail (GCR_IS_IMPORTER (self), FALSE);
+	g_return_val_if_fail (filename, FALSE);
+	g_return_val_if_fail (!error || !*error, FALSE);
+	
+	if (!g_file_get_contents (filename, &data, &n_data, err))
+		return FALSE;
+	
+	ret = gcr_importer_import_data (self, (const guchar*)data, n_data, error);
+	g_free (data);
+	
+	return ret;
+}

Added: trunk/gcr/gcr-importer.h
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-importer.h	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,81 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2008 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __GCR_IMPORTER_H__
+#define __GCR_IMPORTER_H__
+
+#include <glib-object.h>
+
+#define GCR_TYPE_IMPORTER               (gcr_importer_get_type ())
+#define GCR_IMPORTER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_IMPORTER, GcrImporter))
+#define GCR_IMPORTER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_IMPORTER, GcrImporterClass))
+#define GCR_IS_IMPORTER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_IMPORTER))
+#define GCR_IS_IMPORTER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_IMPORTER))
+#define GCR_IMPORTER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_IMPORTER, GcrImporterClass))
+
+typedef struct _GcrImporter GcrImporter;
+typedef struct _GcrImporterClass GcrImporterClass;
+
+struct _GcrImporter {
+	GObject parent;
+};
+
+struct _GcrImporterClass {
+	GObjectClass parent_class;
+    
+	/* signals --------------------------------------------------------- */
+    
+	void (*signal) (GcrImporter *self, GkrImportedItem *item);
+};
+
+GType               gcr_importer_get_type               (void);
+
+GcrImporter*        gcr_importer_new                    (void);
+
+GcrImporter*        gcr_importer_new_for_module         (GP11Module *module);
+
+GcrImporter*        gcr_importer_new_for_module_funcs   (gpointer pkcs11_funcs);
+
+void                gcr_importer_set_slot               (GcrImporter *self,
+                                                         GP11Slot *slot);
+
+void                gcr_importer_set_slot_id            (GcrImporter *self,
+                                                         gulong slot_id);
+
+void                gcr_importer_set_parser             (GcrImporter *self,
+                                                         GcrParser *parser);
+
+void                gcr_importer_set_window             (GcrImporter *self,
+                                                         GtkWindow *window);
+
+void                gcr_importer_set_prompt_behavior    (GcrImporter *self,
+                                                         GcrImporterPromptBehavior behavior);
+
+gboolean            gcr_importer_import_data            (GcrImporter *self,
+                                                         const guchar *data,
+                                                         gsize n_data,
+                                                         GError *error);
+
+gboolean            gcr_importer_import_file            (GcrImporter *self,
+                                                         const gchar *filename,
+                                                         GError *error);
+
+#endif /* __GCR_IMPORTER_H__ */

Added: trunk/gcr/gcr-internal.c
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-internal.c	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,116 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2008 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "config.h"
+
+#include "gcr-internal.h"
+
+#include "egg/egg-secure-memory.h"
+
+#include <gcrypt.h>
+
+static void
+log_handler (gpointer unused, int unknown, const gchar *msg, va_list va)
+{
+	/* TODO: Figure out additional arguments */
+	g_logv ("gcrypt", G_LOG_LEVEL_MESSAGE, msg, va);
+}
+
+static int 
+no_mem_handler (gpointer unused, size_t sz, unsigned int unknown)
+{
+	/* TODO: Figure out additional arguments */
+	g_error ("couldn't allocate %lu bytes of memory", 
+	         (unsigned long int)sz);
+	return 0;
+}
+
+static void
+fatal_handler (gpointer unused, int unknown, const gchar *msg)
+{
+	/* TODO: Figure out additional arguments */
+	g_log ("gcrypt", G_LOG_LEVEL_ERROR, "%s", msg);
+}
+
+static int
+glib_thread_mutex_init (void **lock)
+{
+	*lock = g_mutex_new ();
+	return 0;
+}
+
+static int 
+glib_thread_mutex_destroy (void **lock)
+{
+	g_mutex_free (*lock);
+	return 0;
+}
+
+static int 
+glib_thread_mutex_lock (void **lock)
+{
+	g_mutex_lock (*lock);
+	return 0;
+}
+
+static int 
+glib_thread_mutex_unlock (void **lock)
+{
+	g_mutex_unlock (*lock);
+	return 0;
+}
+
+static struct gcry_thread_cbs glib_thread_cbs = {
+	GCRY_THREAD_OPTION_USER, NULL,
+	glib_thread_mutex_init, glib_thread_mutex_destroy,
+	glib_thread_mutex_lock, glib_thread_mutex_unlock,
+	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL 
+};
+
+void
+_gcr_initialize (void)
+{
+	static gsize gcrypt_initialized = FALSE;
+	unsigned seed;
+
+	if (g_once_init_enter (&gcrypt_initialized)) {
+		
+		/* Only initialize libgcrypt if it hasn't already been initialized */
+		if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P)) {
+			gcry_control (GCRYCTL_SET_THREAD_CBS, &glib_thread_cbs);
+			gcry_check_version (LIBGCRYPT_VERSION);
+			gcry_set_log_handler (log_handler, NULL);
+			gcry_set_outofcore_handler (no_mem_handler, NULL);
+			gcry_set_fatalerror_handler (fatal_handler, NULL);
+			gcry_set_allocation_handler ((gcry_handler_alloc_t)g_malloc, 
+			                             (gcry_handler_alloc_t)egg_secure_alloc, 
+			                             egg_secure_check, 
+			                             (gcry_handler_realloc_t)egg_secure_realloc, 
+			                             egg_secure_free);
+			gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+		}
+		
+		gcry_create_nonce (&seed, sizeof (seed));
+		srand (seed);
+		
+		g_once_init_leave (&gcrypt_initialized, 1);
+	}
+}

Added: trunk/gcr/gcr-internal.h
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-internal.h	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,8 @@
+#ifndef GCR_INTERNAL_H_
+#define GCR_INTERNAL_H_
+
+#include <glib.h>
+
+void _gcr_initialize (void);
+
+#endif /* GCR_INTERNAL_H_ */

Added: trunk/gcr/gcr-marshal.list
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-marshal.list	Sun Jan 18 22:24:09 2009
@@ -0,0 +1 @@
+BOOLEAN:INT

Added: trunk/gcr/gcr-parser.c
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-parser.c	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,1710 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2008 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "config.h"
+
+#include "gp11/gp11.h"
+
+#include "gcr-internal.h"
+#include "gcr-marshal.h"
+#include "gcr-parser.h"
+#include "gcr-types.h"
+
+#include "egg/egg-asn1.h"
+#include "egg/egg-openssl.h"
+#include "egg/egg-secure-memory.h"
+#include "egg/egg-symkey.h"
+
+#include <glib/gi18n-lib.h>
+
+#include <stdlib.h>
+#include <gcrypt.h>
+#include <libtasn1.h>
+
+enum {
+	PROP_0,
+	PROP_PARSED_LABEL,
+	PROP_PARSED_ATTRIBUTES,
+	PROP_PARSED_DESCRIPTION
+};
+
+enum {
+	AUTHENTICATE,
+	PARSED,
+	LAST_SIGNAL
+};
+
+#define SUCCESS 0
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+struct _GcrParserPrivate {
+	GTree *specific_formats;
+	gboolean normal_formats;
+	GPtrArray *passwords;
+	
+	GP11Attributes *parsed_attrs;
+	const gchar *parsed_desc;
+	gchar *parsed_label;
+};
+
+G_DEFINE_TYPE (GcrParser, gcr_parser, G_TYPE_OBJECT);
+
+typedef struct {
+	gint ask_state;
+	gint seen;
+} PasswordState;
+
+#define PASSWORD_STATE_INIT { 0, 0 }
+
+typedef struct _ParserFormat {
+	gint format_id;
+	gint (*function) (GcrParser *self, const guchar *data, gsize n_data);
+} ParserFormat;
+
+/* Forward declarations */
+static const ParserFormat parser_normal[];
+static const ParserFormat parser_formats[];
+static ParserFormat* parser_format_lookup (gint format_id);
+
+/* -----------------------------------------------------------------------------
+ * QUARK DEFINITIONS
+ */
+
+/* 
+ * PEM STRINGS 
+ * The xxxxx in: ----- BEGIN xxxxx ------
+ */ 
+ 
+static GQuark PEM_CERTIFICATE;
+static GQuark PEM_RSA_PRIVATE_KEY;
+static GQuark PEM_DSA_PRIVATE_KEY;
+static GQuark PEM_ANY_PRIVATE_KEY;
+static GQuark PEM_ENCRYPTED_PRIVATE_KEY;
+static GQuark PEM_PRIVATE_KEY;
+static GQuark PEM_PKCS7;
+static GQuark PEM_PKCS12;
+
+/* 
+ * OIDS
+ */
+
+static GQuark OID_PKIX1_RSA;
+static GQuark OID_PKIX1_DSA;
+static GQuark OID_PKCS7_DATA;
+static GQuark OID_PKCS7_SIGNED_DATA;
+static GQuark OID_PKCS7_ENCRYPTED_DATA;
+static GQuark OID_PKCS12_BAG_PKCS8_KEY;
+static GQuark OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY;
+static GQuark OID_PKCS12_BAG_CERTIFICATE;
+static GQuark OID_PKCS12_BAG_CRL;
+
+static void
+init_quarks (void)
+{
+	static volatile gsize quarks_inited = 0;
+
+	if (g_once_init_enter (&quarks_inited)) {
+
+		#define QUARK(name, value) \
+			name = g_quark_from_static_string(value)
+	 
+		QUARK (OID_PKIX1_RSA, "1.2.840.113549.1.1.1");
+		QUARK (OID_PKIX1_DSA, "1.2.840.10040.4.1");
+		QUARK (OID_PKCS7_DATA, "1.2.840.113549.1.7.1");
+		QUARK (OID_PKCS7_SIGNED_DATA, "1.2.840.113549.1.7.2");
+		QUARK (OID_PKCS7_ENCRYPTED_DATA, "1.2.840.113549.1.7.6");
+		QUARK (OID_PKCS12_BAG_PKCS8_KEY, "1.2.840.113549.1.12.10.1.1");
+		QUARK (OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY, "1.2.840.113549.1.12.10.1.2");
+		QUARK (OID_PKCS12_BAG_CERTIFICATE, "1.2.840.113549.1.12.10.1.3");
+		QUARK (OID_PKCS12_BAG_CRL, "1.2.840.113549.1.12.10.1.4");
+		
+		QUARK (PEM_CERTIFICATE, "CERTIFICATE");
+		QUARK (PEM_PRIVATE_KEY, "PRIVATE KEY");
+		QUARK (PEM_RSA_PRIVATE_KEY, "RSA PRIVATE KEY");
+		QUARK (PEM_DSA_PRIVATE_KEY, "DSA PRIVATE KEY");
+		QUARK (PEM_ANY_PRIVATE_KEY, "ANY PRIVATE KEY");
+		QUARK (PEM_ENCRYPTED_PRIVATE_KEY, "ENCRYPTED PRIVATE KEY");
+		QUARK (PEM_PKCS7, "PKCS7");
+		QUARK (PEM_PKCS12, "PKCS12");
+		
+		#undef QUARK
+		
+		g_once_init_leave (&quarks_inited, 1);
+	}
+}
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+static gboolean
+parsed_asn1_attribute (GcrParser *self, ASN1_TYPE asn, const guchar *data, gsize n_data, 
+                       const gchar *part, CK_ATTRIBUTE_TYPE type)
+{
+	const guchar *value;
+	gsize n_value;
+	
+	g_assert (GCR_IS_PARSER (self));
+	g_assert (asn);
+	g_assert (data);
+	g_assert (part);
+	g_assert (self->pv->parsed_attrs);
+	
+	value = egg_asn1_read_content (asn, data, n_data, part, &n_value);
+	if (value == NULL)
+		return FALSE;
+	
+	gp11_attributes_add_data (self->pv->parsed_attrs, type, value, n_value);
+	return TRUE;
+}
+
+static void
+parsed_clear (GcrParser *self, CK_OBJECT_CLASS klass)
+{
+	if (self->pv->parsed_attrs)
+		gp11_attributes_unref (self->pv->parsed_attrs);
+	if (klass == CKO_PRIVATE_KEY)
+		self->pv->parsed_attrs = gp11_attributes_new_full ((GP11Allocator)egg_secure_realloc);
+	else 
+		self->pv->parsed_attrs = gp11_attributes_new ();
+	gp11_attributes_add_ulong (self->pv->parsed_attrs, CKA_CLASS, klass);
+	
+	g_free (self->pv->parsed_label);
+	self->pv->parsed_label = NULL;
+	
+	switch (klass) {
+	case CKO_PRIVATE_KEY:
+		self->pv->parsed_desc = _("Private Key");
+		break;
+	case CKO_CERTIFICATE:
+		self->pv->parsed_desc = _("Certificate");
+		break;
+	case CKO_PUBLIC_KEY:
+		self->pv->parsed_desc = _("Public Key");
+		break;
+	default:
+		self->pv->parsed_desc = NULL;
+		break;
+	}
+}
+
+static void
+parsed_label (GcrParser *self, const gchar *label)
+{
+	g_free (self->pv->parsed_label);
+	self->pv->parsed_label = g_strdup (label);
+}
+
+static void
+parsed_attribute (GcrParser *self, CK_ATTRIBUTE_TYPE type, gconstpointer data, gsize n_data)
+{
+	g_assert (GCR_IS_PARSER (self));
+	g_assert (self->pv->parsed_attrs);
+	gp11_attributes_add_data (self->pv->parsed_attrs, type, data, n_data);
+}
+
+static void
+parsed_ulong (GcrParser *self, CK_ATTRIBUTE_TYPE type, gulong value)
+{
+	g_assert (GCR_IS_PARSER (self));
+	g_assert (self->pv->parsed_attrs);
+	gp11_attributes_add_ulong (self->pv->parsed_attrs, type, value);
+}
+
+static gint
+enum_next_password (GcrParser *self, PasswordState *state, const gchar **password)
+{
+	gboolean result;
+
+	/* 
+	 * Next passes we look through all the passwords that the parser 
+	 * has seen so far. This is because different parts of a encrypted
+	 * container (such as PKCS#12) often use the same password even 
+	 * if with different algorithms. 
+	 * 
+	 * If we didn't do this and the user chooses enters a password, 
+	 * but doesn't save it, they would get prompted for the same thing
+	 * over and over, dumb.  
+	 */
+	
+	/* Look in our list of passwords */
+	if (state->seen < self->pv->passwords->len) {
+		g_assert (state->seen >= 0);
+		*password = g_ptr_array_index (self->pv->passwords, state->seen);
+		++state->seen;
+		return SUCCESS;
+	}
+	
+	/* Fire off all the parsed property signals so anyone watching can update their state */
+	g_object_notify (G_OBJECT (self), "parsed-description");
+	g_object_notify (G_OBJECT (self), "parsed-attributes");
+	g_object_notify (G_OBJECT (self), "parsed-label");
+	
+	g_signal_emit (self, signals[AUTHENTICATE], 0, state->ask_state, &result);
+	++state->ask_state;
+	
+	if (!result)
+		return GCR_PARSE_CANCELLED;
+	
+	/* Return any passwords added */
+	if (state->seen < self->pv->passwords->len) {
+		g_assert (state->seen >= 0);
+		*password = g_ptr_array_index (self->pv->passwords, state->seen);
+		++state->seen;
+		return SUCCESS;
+	}
+	
+	return GCR_PARSE_LOCKED;
+}
+
+static void
+parsed_fire (GcrParser *self)
+{
+	g_object_notify (G_OBJECT (self), "parsed-description");
+	g_object_notify (G_OBJECT (self), "parsed-attributes");
+	g_object_notify (G_OBJECT (self), "parsed-label");
+	
+	g_signal_emit (self, signals[PARSED], 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * RSA PRIVATE KEY
+ */
+
+static gint
+parse_der_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
+{
+	gint res = GCR_PARSE_UNRECOGNIZED;
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	guint version;
+	
+	asn = egg_asn1_decode ("PK.RSAPrivateKey", data, n_data);
+	if (!asn)
+		goto done;
+	
+	parsed_clear (self, CKO_PRIVATE_KEY);
+	parsed_ulong (self, CKA_KEY_TYPE, CKK_RSA);
+	res = GCR_PARSE_FAILURE;
+
+	if (!egg_asn1_read_uint (asn, "version", &version))
+		goto done;
+	
+	/* We only support simple version */
+	if (version != 0) {
+		res = GCR_PARSE_UNRECOGNIZED;
+		g_message ("unsupported version of RSA key: %u", version);
+		goto done;
+	}
+	
+	if (!parsed_asn1_attribute (self, asn, data, n_data, "modulus", CKA_MODULUS) || 
+	    !parsed_asn1_attribute (self, asn, data, n_data, "publicExponent", CKA_PUBLIC_EXPONENT) ||
+	    !parsed_asn1_attribute (self, asn, data, n_data, "privateExponent", CKA_PRIVATE_EXPONENT) ||
+            !parsed_asn1_attribute (self, asn, data, n_data, "prime1", CKA_PRIME_1) ||
+            !parsed_asn1_attribute (self, asn, data, n_data, "prime2", CKA_PRIME_2) || 
+            !parsed_asn1_attribute (self, asn, data, n_data, "coefficient", CKA_COEFFICIENT))
+		goto done;
+	
+	parsed_fire (self);
+	res = SUCCESS;
+
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+
+	if (res == GCR_PARSE_FAILURE)
+		g_message ("invalid RSA key");
+	
+	return res;
+}
+
+/* -----------------------------------------------------------------------------
+ * DSA PRIVATE KEY
+ */
+
+static gint
+parse_der_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
+{
+	gint ret = GCR_PARSE_UNRECOGNIZED;
+	int res;
+	ASN1_TYPE asn;
+
+	asn = egg_asn1_decode ("PK.DSAPrivateKey", data, n_data);
+	if (!asn)
+		goto done;
+	
+	parsed_clear (self, CKO_PRIVATE_KEY);
+	parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
+	res = GCR_PARSE_FAILURE;
+
+	if (!parsed_asn1_attribute (self, asn, data, n_data, "p", CKA_PRIME) ||
+	    !parsed_asn1_attribute (self, asn, data, n_data, "q", CKA_SUBPRIME) ||
+	    !parsed_asn1_attribute (self, asn, data, n_data, "g", CKA_BASE) ||
+	    !parsed_asn1_attribute (self, asn, data, n_data, "priv", CKA_VALUE))
+		goto done;
+		
+	parsed_fire (self);
+	ret = SUCCESS;
+
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+	
+	if (ret == GCR_PARSE_FAILURE) 
+		g_message ("invalid DSA key");
+		
+	return ret;
+}
+
+static gint
+parse_der_private_key_dsa_parts (GcrParser *self, const guchar *keydata, gsize n_keydata,
+                                 const guchar *params, gsize n_params)
+{
+	gint ret = GCR_PARSE_UNRECOGNIZED;
+	int res;
+	ASN1_TYPE asn_params = ASN1_TYPE_EMPTY;
+	ASN1_TYPE asn_key = ASN1_TYPE_EMPTY;
+
+	asn_params = egg_asn1_decode ("PK.DSAParameters", params, n_params);
+	asn_key = egg_asn1_decode ("PK.DSAPrivatePart", keydata, n_keydata);
+	if (!asn_params || !asn_key)
+		goto done;
+	
+	parsed_clear (self, CKO_PRIVATE_KEY);
+	parsed_ulong (self, CKA_KEY_TYPE, CKK_DSA);
+	res = GCR_PARSE_FAILURE;
+    
+	if (!parsed_asn1_attribute (self, asn_params, params, n_params, "p", CKA_PRIME) ||
+	    !parsed_asn1_attribute (self, asn_params, params, n_params, "q", CKA_SUBPRIME) ||
+	    !parsed_asn1_attribute (self, asn_params, params, n_params, "g", CKA_BASE) ||
+	    !parsed_asn1_attribute (self, asn_key, keydata, n_keydata, "", CKA_VALUE))
+		goto done;
+
+	parsed_fire (self);
+	ret = SUCCESS;
+	
+done:
+	if (asn_key)
+		asn1_delete_structure (&asn_key);
+	if (asn_params)
+		asn1_delete_structure (&asn_params);
+	
+	if (ret == GCR_PARSE_FAILURE) 
+		g_message ("invalid DSA key");
+		
+	return ret;	
+}
+
+/* -----------------------------------------------------------------------------
+ * PRIVATE KEY
+ */
+
+static gint
+parse_der_private_key (GcrParser *self, const guchar *data, gsize n_data)
+{
+	gint res;
+	
+	res = parse_der_private_key_rsa (self, data, n_data);
+	if (res == GCR_PARSE_UNRECOGNIZED)
+		res = parse_der_private_key_dsa (self, data, n_data);
+		
+	return res;
+}
+
+/* -----------------------------------------------------------------------------
+ * PKCS8 
+ */
+
+static gint
+parse_der_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gint ret;
+	CK_KEY_TYPE key_type;
+	GQuark key_algo;
+	const guchar *keydata;
+	gsize n_keydata;
+	const guchar *params;
+	gsize n_params;
+	
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-8-PrivateKeyInfo", data, n_data);
+	if (!asn)
+		goto done;
+
+	ret = GCR_PARSE_FAILURE;
+	key_type = GP11_INVALID;
+		
+	key_algo = egg_asn1_read_oid (asn, "privateKeyAlgorithm.algorithm");
+  	if (!key_algo)
+  		goto done;
+  	else if (key_algo == OID_PKIX1_RSA)
+  		key_type = CKK_RSA;
+  	else if (key_algo == OID_PKIX1_DSA)
+  		key_type = CKK_DSA;
+  		
+  	if (key_type == GP11_INVALID) {
+  		ret = GCR_PARSE_UNRECOGNIZED;
+  		goto done;
+  	}
+
+	keydata = egg_asn1_read_content (asn, data, n_data, "privateKey", &n_keydata);
+	if (!keydata)
+		goto done;
+		
+	params = egg_asn1_read_element (asn, data, n_data, "privateKeyAlgorithm.parameters", 
+	                                     &n_params);
+		
+	ret = SUCCESS;
+	
+done:
+	if (ret == SUCCESS) {		
+		switch (key_type) {
+		case CKK_RSA:
+			ret = parse_der_private_key_rsa (self, keydata, n_keydata);
+			break;
+		case CKK_DSA:
+			/* Try the normal sane format */
+			ret = parse_der_private_key_dsa (self, keydata, n_keydata);
+			
+			/* Otherwise try the two part format that everyone seems to like */
+			if (ret == GCR_PARSE_UNRECOGNIZED && params && n_params)
+				ret = parse_der_private_key_dsa_parts (self, keydata, n_keydata, 
+				                                       params, n_params);
+			break;
+		default:
+			g_message ("invalid or unsupported key type in PKCS#8 key");
+			ret = GCR_PARSE_UNRECOGNIZED;
+			break;
+		};
+		
+	} else if (ret == GCR_PARSE_FAILURE) {
+		g_message ("invalid PKCS#8 key");
+	}
+	
+	if (asn)
+		asn1_delete_structure (&asn);
+	return ret;
+}
+
+static gint
+parse_der_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
+{
+	PasswordState pstate = PASSWORD_STATE_INIT;
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_cipher_hd_t cih = NULL;
+	gcry_error_t gcry;
+	gint ret, r;
+	GQuark scheme;
+	guchar *crypted = NULL;
+	const guchar *params;
+	gsize n_crypted, n_params;
+	const gchar *password;
+	gint l;
+
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
+	if (!asn)
+		goto done;
+
+	ret = GCR_PARSE_FAILURE;
+
+	/* Figure out the type of encryption */
+	scheme = egg_asn1_read_oid (asn, "encryptionAlgorithm.algorithm");
+	if (!scheme)
+		goto done;
+		
+	params = egg_asn1_read_element (asn, data, n_data, "encryptionAlgorithm.parameters", &n_params);
+	
+	parsed_clear (self, CKO_PRIVATE_KEY);
+
+	/* Loop to try different passwords */                       
+	for (;;) {
+		
+		g_assert (cih == NULL);
+		
+		r = enum_next_password (self, &pstate, &password);
+		if (r != SUCCESS) {
+			ret = r;
+			break;
+		}
+	        
+		/* Parse the encryption stuff into a cipher. */
+		if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih))
+			break;
+			
+		crypted = egg_asn1_read_value (asn, "encryptedData", &n_crypted, egg_secure_realloc);
+		if (!crypted)
+			break;
+	
+		gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
+		gcry_cipher_close (cih);
+		cih = NULL;
+		
+		if (gcry != 0) {
+			g_warning ("couldn't decrypt pkcs8 data: %s", gcry_strerror (gcry));
+			break;
+		}
+		
+		/* Unpad the DER data */
+		l = egg_asn1_element_length (crypted, n_crypted);
+		if (l > 0)
+			n_crypted = l;
+		
+		/* Try to parse the resulting key */
+		r = parse_der_pkcs8_plain (self, crypted, n_crypted);
+		egg_secure_free (crypted);
+		crypted = NULL;
+		
+		if (r != GCR_PARSE_UNRECOGNIZED) {
+			ret = r;
+			break;
+		}
+		
+		/* We assume unrecognized data, is a bad encryption key */	
+	}
+		
+done:
+	if (cih)
+		gcry_cipher_close (cih);
+	if (asn)
+		asn1_delete_structure (&asn);
+	egg_secure_free (crypted);
+		
+	return ret;
+}
+
+static gint
+parse_der_pkcs8 (GcrParser *self, const guchar *data, gsize n_data)
+{
+	gint ret;
+	
+	ret = parse_der_pkcs8_plain (self, data, n_data);
+	if (ret == GCR_PARSE_UNRECOGNIZED)
+		ret = parse_der_pkcs8_encrypted (self, data, n_data);
+	
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * CERTIFICATE
+ */
+
+static gint
+parse_der_certificate (GcrParser *self, const guchar *data, gsize n_data)
+{
+	ASN1_TYPE asn;
+	gchar *name;
+	
+	asn = egg_asn1_decode ("PKIX1.Certificate", data, n_data);
+	if (asn == NULL)
+		return GCR_PARSE_UNRECOGNIZED;
+
+	parsed_clear (self, CKO_CERTIFICATE);
+	parsed_ulong (self, CKA_CERTIFICATE_TYPE, CKC_X_509);
+
+	name = egg_asn1_read_dn_part (asn, "tbsCertificate.subject.rdnSequence", "CN");
+	asn1_delete_structure (&asn);
+		
+	if (name != NULL) {
+		parsed_label (self, name);
+		g_free (name);
+	}
+
+	parsed_attribute (self, CKA_VALUE, data, n_data);
+	parsed_fire (self);
+	
+	return SUCCESS;
+}
+
+/* -----------------------------------------------------------------------------
+ * PKCS7
+ */
+
+static gint
+handle_pkcs7_signed_data (GcrParser *self, const guchar *data, gsize n_data)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gint ret;
+	gchar *part;
+	const guchar *certificate;
+	gsize n_certificate;
+	int i;
+	
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-7-SignedData", data, n_data);
+	if (!asn)
+		goto done;
+
+	ret = GCR_PARSE_FAILURE;
+	
+	for (i = 0; TRUE; ++i) {
+			
+		part = g_strdup_printf ("certificates.?%u", i + 1);
+		certificate = egg_asn1_read_element (asn, data, n_data, part, &n_certificate);
+		g_free (part);
+		
+		/* No more certificates? */
+		if (!certificate)
+			break;
+	
+		ret = parse_der_certificate (self, certificate, n_certificate);
+		if (ret != SUCCESS)
+			goto done;
+	}
+	
+	/* TODO: Parse out all the CRLs */
+	
+	ret = SUCCESS;
+	
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+	
+	return ret;
+}
+
+static gint
+parse_der_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gint ret;
+	const guchar* content = NULL;
+	gsize n_content;
+	GQuark oid;
+	
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-7-ContentInfo", data, n_data);
+	if (!asn)
+		goto done;
+
+	ret = GCR_PARSE_FAILURE;
+
+	oid = egg_asn1_read_oid (asn, "contentType");
+	if (!oid)
+		goto done;
+
+	/* Outer most one must just be plain data */
+	if (oid != OID_PKCS7_SIGNED_DATA) {
+		g_message ("unsupported outer content type in pkcs7: %s", g_quark_to_string (oid));
+		goto done;
+	}
+	
+	content = egg_asn1_read_content (asn, data, n_data, "content", &n_content);
+	if (!content) 
+		goto done;
+		
+	ret = handle_pkcs7_signed_data (self, content, n_content);
+			
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * PKCS12
+ */
+
+static gint
+handle_pkcs12_cert_bag (GcrParser *self, const guchar *data, gsize n_data)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	const guchar *certificate;
+	gsize n_certificate;
+	gint ret;
+
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-12-CertBag", data, n_data);
+	if (!asn)
+		goto done;
+		
+	ret = GCR_PARSE_FAILURE;
+	
+	certificate = egg_asn1_read_content (asn, data, n_data, "certValue", &n_certificate);
+	if (!certificate)
+		goto done;
+
+	/* 
+	 * Wrapped in an OCTET STRING, so unwrap here, rather than allocating 
+	 * a whole bunch more memory for a full ASN.1 parsing context.
+	 */ 
+	certificate = egg_asn1_element_content (certificate, n_certificate, &n_certificate);
+	if (!certificate)
+		goto done;
+	
+	ret = parse_der_certificate (self, certificate, n_certificate);
+		
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+		
+	return ret;
+}
+
+static gint
+handle_pkcs12_bag (GcrParser *self, const guchar *data, gsize n_data)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gint ret, r;
+	int res, count = 0;
+	GQuark oid;
+	const guchar *element;
+	gsize n_element;
+	
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-12-SafeContents", data, n_data);
+	if (!asn)
+		goto done;
+		
+	ret = GCR_PARSE_FAILURE;
+	
+	/* Get the number of elements in this bag */
+	res = asn1_number_of_elements (asn, "", &count);
+	if (res != ASN1_SUCCESS)
+		goto done;	
+	
+	/* 
+	 * Now inside each bag are multiple elements. Who comes up 
+	 * with this stuff?
+	 * 
+	 * But this is where we draw the line. We only support one
+	 * element per bag, not multiple elements, not strange
+	 * nested bags, not fairy queens with magical wands in bags...
+	 * 
+	 * Just one element per bag.
+	 */
+	if (count >= 1) {
+
+		oid = egg_asn1_read_oid (asn, "?1.bagId");
+		if (!oid)
+			goto done;
+		
+		element = egg_asn1_read_content (asn, data, n_data, "?1.bagValue", &n_element); 	
+		if (!element)
+			goto done;
+
+		/* A normal unencrypted key */
+		if (oid == OID_PKCS12_BAG_PKCS8_KEY) {
+			r = parse_der_pkcs8_plain (self, element, n_element);
+			
+		/* A properly encrypted key */
+		} else if (oid == OID_PKCS12_BAG_PKCS8_ENCRYPTED_KEY) {
+			r = parse_der_pkcs8_encrypted (self, element, n_element);
+			
+		/* A certificate */
+		} else if (oid == OID_PKCS12_BAG_CERTIFICATE) {
+			r = handle_pkcs12_cert_bag (self, element, n_element);
+								
+		/* TODO: OID_PKCS12_BAG_CRL */
+		} else {
+			r = GCR_PARSE_UNRECOGNIZED;
+		}
+		 
+		if (r == GCR_PARSE_FAILURE || r == GCR_PARSE_CANCELLED) {
+			ret = r;
+			goto done;
+		}
+	}
+
+	ret = SUCCESS;	
+		
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+		
+	return ret;
+}
+
+static gint
+handle_pkcs12_encrypted_bag (GcrParser *self, const guchar *data, gsize n_data)
+{
+	PasswordState pstate = PASSWORD_STATE_INIT;
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_cipher_hd_t cih = NULL;
+	gcry_error_t gcry;
+	guchar *crypted = NULL;
+	const guchar *params;
+	gsize n_params, n_crypted;
+	const gchar *password;
+	GQuark scheme;
+	gint ret, r;
+	gint l;
+	
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-7-EncryptedData", data, n_data);
+	if (!asn)
+		goto done;
+	
+	ret = GCR_PARSE_FAILURE;
+		
+	/* Check the encryption schema OID */
+	scheme = egg_asn1_read_oid (asn, "encryptedContentInfo.contentEncryptionAlgorithm.algorithm");
+	if (!scheme) 
+		goto done;	
+
+	params = egg_asn1_read_element (asn, data, n_data, "encryptedContentInfo.contentEncryptionAlgorithm.parameters", &n_params);
+	if (!params)
+		goto done;
+	
+	parsed_clear (self, 0);
+
+	/* Loop to try different passwords */
+	for (;;) {
+		
+		g_assert (cih == NULL);
+		
+		r = enum_next_password (self, &pstate, &password);
+		if (r != SUCCESS) {
+			ret = r;
+			goto done;
+		}
+	        
+		/* Parse the encryption stuff into a cipher. */
+		if (!egg_symkey_read_cipher (scheme, password, -1, params, n_params, &cih)) {
+			ret = GCR_PARSE_FAILURE;
+			goto done;
+		}
+			
+		crypted = egg_asn1_read_value (asn, "encryptedContentInfo.encryptedContent", 
+		                               &n_crypted, egg_secure_realloc);
+		if (!crypted)
+			goto done;
+	
+		gcry = gcry_cipher_decrypt (cih, crypted, n_crypted, NULL, 0);
+		gcry_cipher_close (cih);
+		cih = NULL;
+		
+		if (gcry != 0) {
+			g_warning ("couldn't decrypt pkcs7 data: %s", gcry_strerror (gcry));
+			goto done;
+		}
+		
+		/* Unpad the DER data */
+		l = egg_asn1_element_length (crypted, n_crypted);
+		if (l > 0)
+			n_crypted = l;
+
+		/* Try to parse the resulting key */
+		r = handle_pkcs12_bag (self, crypted, n_crypted);
+		egg_secure_free (crypted);
+		crypted = NULL;
+		
+		if (r != GCR_PARSE_UNRECOGNIZED) {
+			ret = r;
+			break;
+		}
+		
+		/* We assume unrecognized data is a bad encryption key */	
+	}
+		
+done:
+	if (cih)
+		gcry_cipher_close (cih);
+	if (asn)
+		asn1_delete_structure (&asn);
+	egg_secure_free (crypted);
+	
+	return ret;
+}
+
+static gint
+handle_pkcs12_safe (GcrParser *self, const guchar *data, gsize n_data)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gint ret, r;
+	const guchar *bag;
+	gsize n_bag;
+	gchar *part;
+	GQuark oid;
+	guint i;
+	
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-12-AuthenticatedSafe", data, n_data);
+	if (!asn)
+		goto done;
+		
+	ret = GCR_PARSE_FAILURE;
+	
+	/*
+	 * Inside each PKCS12 safe there are multiple bags. 
+	 */
+	for (i = 0; TRUE; ++i) {
+		
+		part = g_strdup_printf ("?%u.contentType", i + 1);
+		oid = egg_asn1_read_oid (asn, part);
+		g_free (part);
+		
+		/* All done? no more bags */
+		if (!oid) 
+			break;
+		
+		part = g_strdup_printf ("?%u.content", i + 1);
+		bag = egg_asn1_read_content (asn, data, n_data, part, &n_bag);
+		g_free (part);
+		
+		if (!bag) /* A parse error */
+			goto done;
+			
+		/* A non encrypted bag, just parse */
+		if (oid == OID_PKCS7_DATA) {
+			
+			/* 
+		 	 * Wrapped in an OCTET STRING, so unwrap here, rather than allocating 
+		 	 * a whole bunch more memory for a full ASN.1 parsing context.
+		 	 */ 
+			bag = egg_asn1_element_content (bag, n_bag, &n_bag);
+			if (!bag)
+				goto done;	
+			
+			r = handle_pkcs12_bag (self, bag, n_bag);
+
+		/* Encrypted data first needs decryption */
+		} else if (oid == OID_PKCS7_ENCRYPTED_DATA) {
+			r = handle_pkcs12_encrypted_bag (self, bag, n_bag);
+		
+		/* Hmmmm, not sure what this is */
+		} else {
+			g_warning ("unrecognized type of safe content in pkcs12: %s", g_quark_to_string (oid));
+			r = GCR_PARSE_UNRECOGNIZED;
+		}
+		
+		if (r == GCR_PARSE_FAILURE || r == GCR_PARSE_CANCELLED) {
+			ret = r;
+			goto done;
+		}
+	}
+	
+	ret = SUCCESS;
+	
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+		
+	return ret;
+}
+
+static gint
+parse_der_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gint ret;
+	const guchar* content = NULL;
+	gsize n_content;
+	GQuark oid;
+	
+	ret = GCR_PARSE_UNRECOGNIZED;
+	
+	asn = egg_asn1_decode ("PKIX1.pkcs-12-PFX", data, n_data);
+	if (!asn)
+		goto done;
+
+	oid = egg_asn1_read_oid (asn, "authSafe.contentType");
+	if (!oid)
+		goto done;
+		
+	/* Outer most one must just be plain data */
+	if (oid != OID_PKCS7_DATA) {
+		g_message ("unsupported safe content type in pkcs12: %s", g_quark_to_string (oid));
+		goto done;
+	}
+	
+	content = egg_asn1_read_content (asn, data, n_data, "authSafe.content", &n_content);
+	if (!content)
+		goto done;
+		
+	/* 
+	 * Wrapped in an OCTET STRING, so unwrap here, rather than allocating 
+	 * a whole bunch more memory for a full ASN.1 parsing context.
+	 */ 
+	content = egg_asn1_element_content (content, n_content, &n_content);
+	if (!content)
+		goto done;
+				
+	ret = handle_pkcs12_safe (self, content, n_content);
+	
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+	return ret;
+}
+
+/* -----------------------------------------------------------------------------
+ * PEM PARSING 
+ */
+
+static gint
+handle_plain_pem (GcrParser *self, GQuark type, gint subformat, 
+                  const guchar *data, gsize n_data)
+{
+	ParserFormat *format;
+	gint format_id;
+	
+	if (type == PEM_RSA_PRIVATE_KEY)
+		format_id = GCR_FORMAT_DER_PRIVATE_KEY_RSA;
+
+	else if (type == PEM_DSA_PRIVATE_KEY)
+		format_id = GCR_FORMAT_DER_PRIVATE_KEY_DSA;
+
+	else if (type == PEM_ANY_PRIVATE_KEY)
+		format_id = GCR_FORMAT_DER_PRIVATE_KEY;
+	
+	else if (type == PEM_PRIVATE_KEY)
+		format_id = GCR_FORMAT_DER_PKCS8_PLAIN;
+		
+	else if (type == PEM_ENCRYPTED_PRIVATE_KEY)
+		format_id = GCR_FORMAT_DER_PKCS8_ENCRYPTED;
+
+	else if (type == PEM_CERTIFICATE)
+		format_id = GCR_FORMAT_DER_CERTIFICATE_X509;
+
+	else if (type == PEM_PKCS7)
+		format_id = GCR_FORMAT_DER_PKCS7;
+		
+	else if (type == PEM_PKCS12)
+		format_id = GCR_FORMAT_DER_PKCS12;
+		
+	else
+		return GCR_PARSE_UNRECOGNIZED;
+
+	if (subformat != 0 && subformat != format_id)
+		return GCR_PARSE_UNRECOGNIZED;
+	
+	format = parser_format_lookup (format_id);
+	if (format == NULL)
+		return GCR_PARSE_UNRECOGNIZED;
+	
+	return (format->function) (self, data, n_data);
+}
+
+static CK_OBJECT_CLASS
+pem_type_to_class (gint type)
+{
+	if (type == PEM_RSA_PRIVATE_KEY ||
+	    type == PEM_DSA_PRIVATE_KEY ||
+	    type == PEM_ANY_PRIVATE_KEY ||
+	    type == PEM_PRIVATE_KEY ||
+	    type == PEM_ENCRYPTED_PRIVATE_KEY)
+		return CKO_PRIVATE_KEY;
+
+	else if (type == PEM_CERTIFICATE)
+		return CKO_CERTIFICATE;
+		
+	else if (type == PEM_PKCS7 ||
+	         type == PEM_PKCS12)
+		return 0;
+
+	return 0;
+}
+
+static gint
+handle_encrypted_pem (GcrParser *self, GQuark type, gint subformat, 
+                      GHashTable *headers, const guchar *data, gsize n_data)
+{
+	PasswordState pstate = PASSWORD_STATE_INIT;
+	const gchar *password;
+	guchar *decrypted;
+	gsize n_decrypted;
+	const gchar *val;
+	gboolean ret;
+	gint res;
+	gint l;
+	
+	g_assert (GCR_IS_PARSER (self));
+	g_assert (headers);
+	g_assert (type);
+	
+	val = g_hash_table_lookup (headers, "DEK-Info");
+	if (!val) {
+		g_message ("missing encryption header");
+		return GCR_PARSE_FAILURE;
+	}
+	
+	/* Fill in information necessary for prompting */
+	parsed_clear (self, pem_type_to_class (type));
+	
+	for (;;) {
+
+		res = enum_next_password (self, &pstate, &password);
+		if (res != SUCCESS)
+			return res;
+		
+		decrypted = NULL;
+		n_decrypted = 0;
+		
+		/* Decrypt, this will result in garble if invalid password */	
+		ret = egg_openssl_decrypt_block (val, password, -1, data, n_data, 
+		                                 &decrypted, &n_decrypted);
+		if (!ret)
+			return GCR_PARSE_FAILURE;
+			
+		g_assert (decrypted);
+		
+		/* Unpad the DER data */
+		l = egg_asn1_element_length (decrypted, n_decrypted);
+		if (l > 0)
+			n_decrypted = l;
+	
+		/* Try to parse */
+		res = handle_plain_pem (self, type, subformat, decrypted, n_decrypted);
+		egg_secure_free (decrypted);
+
+		/* Unrecognized is a bad password */
+		if (res != GCR_PARSE_UNRECOGNIZED)
+			return res;		
+	}
+	
+	return GCR_PARSE_FAILURE;
+}
+
+typedef struct {
+	GcrParser *parser;
+	gint result;
+	gint subformat;
+} HandlePemArgs;
+
+static void
+handle_pem_data (GQuark type, const guchar *data, gsize n_data,
+                 GHashTable *headers, gpointer user_data)
+{
+	HandlePemArgs *args = (HandlePemArgs*)user_data;
+	gint res = GCR_PARSE_FAILURE;
+	gboolean encrypted = FALSE;
+	const gchar *val;
+	
+	/* Something already failed to parse */
+	if (args->result == GCR_PARSE_FAILURE)
+		return;
+	
+	/* See if it's encrypted PEM all openssl like*/
+	if (headers) {
+		val = g_hash_table_lookup (headers, "Proc-Type");
+		if (val && strcmp (val, "4,ENCRYPTED") == 0) 
+			encrypted = TRUE;
+	}
+	
+	if (encrypted)
+		res = handle_encrypted_pem (args->parser, type, args->subformat,  
+		                            headers, data, n_data); 
+	else
+		res = handle_plain_pem (args->parser, type, args->subformat, 
+		                        data, n_data);
+	
+	if (res != GCR_PARSE_UNRECOGNIZED) {
+		if (args->result == GCR_PARSE_UNRECOGNIZED)
+			args->result = res;
+		else if (res > args->result)
+			args->result = res;
+	}
+}
+
+static gint
+handle_pem_format (GcrParser *self, gint subformat, const guchar *data, gsize n_data)
+{
+	HandlePemArgs ctx = { self, GCR_PARSE_UNRECOGNIZED, subformat };
+	guint found;
+	
+	if (n_data == 0)
+		return GCR_PARSE_UNRECOGNIZED;
+	
+	found = egg_openssl_pem_parse (data, n_data, handle_pem_data, &ctx);
+	
+	if (found == 0)
+		return GCR_PARSE_UNRECOGNIZED;
+		
+	return ctx.result;
+}
+
+
+static gint
+parse_pem (GcrParser *self, const guchar *data, gsize n_data)
+{
+	return handle_pem_format (self, 0, data, n_data);
+}
+
+static gint 
+parse_pem_private_key_rsa (GcrParser *self, const guchar *data, gsize n_data)
+{
+	return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_RSA, data, n_data);
+}
+
+static gint 
+parse_pem_private_key_dsa (GcrParser *self, const guchar *data, gsize n_data)
+{
+	return handle_pem_format (self, GCR_FORMAT_DER_PRIVATE_KEY_DSA, data, n_data);
+}
+
+static gint 
+parse_pem_certificate (GcrParser *self, const guchar *data, gsize n_data)
+{
+	return handle_pem_format (self, GCR_FORMAT_PEM_CERTIFICATE_X509, data, n_data);
+}
+
+static gint 
+parse_pem_pkcs8_plain (GcrParser *self, const guchar *data, gsize n_data)
+{
+	return handle_pem_format (self, GCR_FORMAT_PEM_PKCS8_PLAIN, data, n_data);
+}
+
+static gint 
+parse_pem_pkcs8_encrypted (GcrParser *self, const guchar *data, gsize n_data)
+{
+	return handle_pem_format (self, GCR_FORMAT_PEM_PKCS8_ENCRYPTED, data, n_data);
+}
+
+static gint 
+parse_pem_pkcs7 (GcrParser *self, const guchar *data, gsize n_data)
+{
+	return handle_pem_format (self, GCR_FORMAT_PEM_PKCS7, data, n_data);
+}
+
+static gint 
+parse_pem_pkcs12 (GcrParser *self, const guchar *data, gsize n_data)
+{
+	return handle_pem_format (self, GCR_FORMAT_PEM_PKCS12, data, n_data);
+}
+
+/* -----------------------------------------------------------------------------
+ * FORMATS
+ */
+
+/* In order of parsing when no formats specified */
+static const ParserFormat parser_normal[] = {
+	{ GCR_FORMAT_PEM, parse_pem },
+	{ GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
+	{ GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
+	{ GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
+	{ GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
+	{ GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
+	{ GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
+	{ GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 }
+};
+
+/* Must be in format_id numeric order */
+static const ParserFormat parser_formats[] = {
+	{ GCR_FORMAT_DER_PRIVATE_KEY, parse_der_private_key },
+	{ GCR_FORMAT_DER_PRIVATE_KEY_RSA, parse_der_private_key_rsa },
+	{ GCR_FORMAT_DER_PRIVATE_KEY_DSA, parse_der_private_key_dsa },
+	{ GCR_FORMAT_DER_CERTIFICATE_X509, parse_der_certificate },
+	{ GCR_FORMAT_DER_PKCS7, parse_der_pkcs7 },
+	{ GCR_FORMAT_DER_PKCS8, parse_der_pkcs8 },
+	{ GCR_FORMAT_DER_PKCS8_PLAIN, parse_der_pkcs8_plain },
+	{ GCR_FORMAT_DER_PKCS8_ENCRYPTED, parse_der_pkcs8_encrypted },
+	{ GCR_FORMAT_DER_PKCS12, parse_der_pkcs12 },
+	{ GCR_FORMAT_PEM, parse_pem },
+	{ GCR_FORMAT_PEM_PRIVATE_KEY_RSA, parse_pem_private_key_rsa },
+	{ GCR_FORMAT_PEM_PRIVATE_KEY_DSA, parse_pem_private_key_dsa },
+	{ GCR_FORMAT_PEM_CERTIFICATE_X509, parse_pem_certificate },
+	{ GCR_FORMAT_PEM_PKCS7, parse_pem_pkcs7 },
+	{ GCR_FORMAT_PEM_PKCS8_PLAIN, parse_pem_pkcs8_plain },
+	{ GCR_FORMAT_PEM_PKCS8_ENCRYPTED, parse_pem_pkcs8_encrypted },
+	{ GCR_FORMAT_PEM_PKCS12, parse_pem_pkcs12 },
+};
+
+static int
+compar_id_to_parser_format (const void *a, const void *b)
+{
+	const gint *format_id = a;
+	const ParserFormat *format = b;
+	
+	g_assert (format_id);
+	g_assert (format);
+	
+	if (format->format_id == *format_id)
+		return 0;
+	return (*format_id < format->format_id) ? -1 : 1;
+}
+
+static ParserFormat*
+parser_format_lookup (gint format_id)
+{
+	return bsearch (&format_id, parser_formats, G_N_ELEMENTS (parser_formats),
+	                sizeof (parser_formats[0]), compar_id_to_parser_format);
+}
+
+static gint
+compare_pointers (gconstpointer a, gconstpointer b)
+{
+	if (a == b)
+		return 0;
+	return a < b ? -1 : 1;
+}
+
+typedef struct _ForeachArgs {
+	GcrParser *parser;
+	const guchar *data;
+	gsize n_data;
+	gint result;
+} ForeachArgs;
+
+static gboolean
+parser_format_foreach (gpointer key, gpointer value, gpointer data)
+{
+	ForeachArgs *args = data;
+	ParserFormat *format = key;
+	gint result;
+	
+	g_assert (format);
+	g_assert (format->function);
+	g_assert (GCR_IS_PARSER (args->parser));
+	
+	result = (format->function) (args->parser, args->data, args->n_data);
+	if (result != GCR_PARSE_UNRECOGNIZED) {
+		args->result = result;
+		return TRUE;
+	}
+	
+	/* Keep going */
+	return FALSE;
+}
+
+/* -----------------------------------------------------------------------------
+ * OBJECT 
+ */
+
+
+static GObject* 
+gcr_parser_constructor (GType type, guint n_props, GObjectConstructParam *props) 
+{
+	GcrParser *self = GCR_PARSER (G_OBJECT_CLASS (gcr_parser_parent_class)->constructor(type, n_props, props));
+	g_return_val_if_fail (self, NULL);	
+
+	/* Always try to parse with NULL and empty passwords first */
+	gcr_parser_add_password (self, NULL);
+	gcr_parser_add_password (self, "");
+	
+	return G_OBJECT (self);
+}
+
+static void
+gcr_parser_init (GcrParser *self)
+{
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_PARSER, GcrParserPrivate);
+	self->pv->passwords = g_ptr_array_new ();
+	self->pv->normal_formats = TRUE;
+}
+
+static void
+gcr_parser_dispose (GObject *obj)
+{
+	GcrParser *self = GCR_PARSER (obj);
+	gsize i;
+	
+	if (self->pv->parsed_attrs)
+		gp11_attributes_unref (self->pv->parsed_attrs);
+	self->pv->parsed_attrs = NULL;
+	
+	g_free (self->pv->parsed_label);
+	self->pv->parsed_label = NULL;
+	
+	for (i = 0; i < self->pv->passwords->len; ++i)
+		egg_secure_strfree (g_ptr_array_index (self->pv->passwords, i));
+	g_ptr_array_set_size (self->pv->passwords, 0);
+	
+	G_OBJECT_CLASS (gcr_parser_parent_class)->dispose (obj);
+}
+
+static void
+gcr_parser_finalize (GObject *obj)
+{
+	GcrParser *self = GCR_PARSER (obj);
+	
+	g_assert (!self->pv->parsed_attrs);
+	g_assert (!self->pv->parsed_label);
+
+	g_ptr_array_free (self->pv->passwords, TRUE);
+	self->pv->passwords = NULL;
+
+	G_OBJECT_CLASS (gcr_parser_parent_class)->finalize (obj);
+}
+
+static void
+gcr_parser_set_property (GObject *obj, guint prop_id, const GValue *value, 
+                           GParamSpec *pspec)
+{
+#if 0
+	GcrParser *self = GCR_PARSER (obj);
+#endif
+	switch (prop_id) {
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gcr_parser_get_property (GObject *obj, guint prop_id, GValue *value, 
+                         GParamSpec *pspec)
+{
+	GcrParser *self = GCR_PARSER (obj);
+	
+	switch (prop_id) {
+	case PROP_PARSED_ATTRIBUTES:
+		g_value_set_boxed (value, gcr_parser_get_parsed_attributes (self));
+		break;
+	case PROP_PARSED_LABEL:
+		g_value_set_string (value, gcr_parser_get_parsed_label (self));
+		break;
+	case PROP_PARSED_DESCRIPTION:
+		g_value_set_string (value, gcr_parser_get_parsed_description (self));
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gcr_parser_class_init (GcrParserClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	gint i;
+    
+	gobject_class->constructor = gcr_parser_constructor;
+	gobject_class->dispose = gcr_parser_dispose;
+	gobject_class->finalize = gcr_parser_finalize;
+	gobject_class->set_property = gcr_parser_set_property;
+	gobject_class->get_property = gcr_parser_get_property;
+    
+	g_type_class_add_private (gobject_class, sizeof (GcrParserPrivate));
+	
+	g_object_class_install_property (gobject_class, PROP_PARSED_ATTRIBUTES,
+	           g_param_spec_boxed ("parsed-attributes", "Parsed Attributes", "Parsed PKCS#11 attributes", 
+	                               GP11_TYPE_ATTRIBUTES, G_PARAM_READABLE));
+
+	g_object_class_install_property (gobject_class, PROP_PARSED_LABEL,
+	           g_param_spec_string ("parsed-label", "Parsed Label", "Parsed item label", 
+	                                "", G_PARAM_READABLE));
+
+	g_object_class_install_property (gobject_class, PROP_PARSED_DESCRIPTION,
+	           g_param_spec_string ("parsed-description", "Parsed Description", "Parsed item description", 
+	                                "", G_PARAM_READABLE));
+    
+	signals[AUTHENTICATE] = g_signal_new ("authenticate", GCR_TYPE_PARSER, 
+	                                G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GcrParserClass, authenticate),
+	                                g_signal_accumulator_true_handled, NULL, _gcr_marshal_BOOLEAN__INT, 
+	                                G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
+
+	signals[PARSED] = g_signal_new ("parsed", GCR_TYPE_PARSER, 
+	                                G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrParserClass, parsed),
+	                                NULL, NULL, g_cclosure_marshal_VOID__VOID, 
+	                                G_TYPE_NONE, 0);
+	
+	init_quarks ();
+	_gcr_initialize ();
+	
+	/* Check that the format tables are in order */
+	for (i = 1; i < G_N_ELEMENTS (parser_formats); ++i)
+		g_assert (parser_formats[i].format_id >= parser_formats[i - 1].format_id);
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC 
+ */
+
+GcrParser*
+gcr_parser_new (void)
+{
+	return g_object_new (GCR_TYPE_PARSER, NULL);
+}
+
+GQuark
+gcr_parser_get_error_domain (void)
+{
+	static GQuark domain = 0;
+	if (domain == 0)
+		domain = g_quark_from_static_string ("gcr-parser-error");
+	return domain;
+}
+
+void
+gcr_parser_add_password (GcrParser *self, const gchar *password)
+{
+	g_return_if_fail (GCR_IS_PARSER (self));
+	g_ptr_array_add (self->pv->passwords, egg_secure_strdup (password));
+}
+
+gboolean
+gcr_parser_parse_data (GcrParser *self, const guchar *data, 
+                       gsize n_data, GError **err)
+{
+	ForeachArgs args = { self, data, n_data, GCR_PARSE_UNRECOGNIZED };
+	const gchar *message;
+	gint i;
+	
+	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+	g_return_val_if_fail (data || !n_data, FALSE);
+	g_return_val_if_fail (!err || !*err, FALSE);
+
+	/* Just the specific formats requested */
+	if (self->pv->specific_formats) { 
+		g_tree_foreach (self->pv->specific_formats, parser_format_foreach, &args);
+		
+	/* All the 'normal' formats */
+	} else if (self->pv->normal_formats) {
+		for (i = 0; i < G_N_ELEMENTS (parser_normal); ++i) {
+			if (parser_format_foreach ((gpointer)(parser_normal + i), 
+			                           (gpointer)(parser_normal + i), &args))
+				break;
+		}
+	}
+	
+	switch (args.result) {
+	case SUCCESS:
+		return TRUE;
+	case GCR_PARSE_CANCELLED:
+		message = _("The operation was cancelled");
+		break;
+	case GCR_PARSE_UNRECOGNIZED:
+		message = _("Unrecognized or unsupported data.");
+		break;
+	case GCR_PARSE_FAILURE:
+		message = _("Could not parse invalid or corrupted data.");
+		break;
+	case GCR_PARSE_LOCKED:
+		message = _("The data is locked");
+		break;
+	default:
+		g_assert_not_reached ();
+		break;
+	};
+	
+	g_set_error_literal (err, GCR_PARSER_ERROR, args.result, message);
+	return FALSE;
+}
+
+gboolean
+gcr_parser_parse_file (GcrParser *self, const gchar *filename, GError **err)
+{
+	GMappedFile *mapped;
+	gboolean ret;
+	const guchar *data;
+	gsize n_data; 
+	
+	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+	g_return_val_if_fail (filename, FALSE);
+	g_return_val_if_fail (!err || !*err, FALSE);
+	
+	mapped = g_mapped_file_new (filename, FALSE, err);
+	if (mapped == NULL)
+		return FALSE;
+
+	data = (const guchar*)g_mapped_file_get_contents (mapped);
+	n_data = g_mapped_file_get_length (mapped);
+	
+	ret = gcr_parser_parse_data (self, data, n_data, err);
+		
+	g_mapped_file_free (mapped);
+	
+	return ret;
+}
+
+gboolean
+gcr_parser_format_enable (GcrParser *self, gint format_id)
+{
+	ParserFormat *format;
+	
+	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+	
+	if (format_id == -1) {
+		if (self->pv->specific_formats)
+			g_tree_destroy (self->pv->specific_formats);
+		self->pv->specific_formats = NULL;
+		self->pv->normal_formats = TRUE;
+		return TRUE;
+	}
+	
+	format = parser_format_lookup (format_id);
+	if (format == NULL)
+		return FALSE;
+	
+	if (!self->pv->specific_formats) {
+		if (self->pv->normal_formats)
+			return TRUE;
+		self->pv->specific_formats = g_tree_new (compare_pointers);
+	}
+	
+	g_tree_insert (self->pv->specific_formats, format, format);
+	return TRUE;
+}
+
+gboolean
+gcr_parser_format_disable (GcrParser *self, gint format_id)
+{
+	ParserFormat *format;
+	
+	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+	
+	if (format_id == -1) {
+		if (self->pv->specific_formats)
+			g_tree_destroy (self->pv->specific_formats);
+		self->pv->specific_formats = NULL;
+		self->pv->normal_formats = FALSE;
+		return TRUE;
+	}
+	
+	if (!self->pv->specific_formats)
+		return TRUE;
+	
+	format = parser_format_lookup (format_id);
+	if (format == NULL)
+		return FALSE;
+	
+	g_tree_remove (self->pv->specific_formats, format);
+	return TRUE;
+}
+
+gboolean
+gcr_parser_format_supported (GcrParser *self, gint format_id)
+{
+	g_return_val_if_fail (GCR_IS_PARSER (self), FALSE);
+	g_return_val_if_fail (format_id != -1, FALSE);
+	return parser_format_lookup (format_id) ? TRUE : FALSE;	
+}
+
+const gchar*
+gcr_parser_get_parsed_description (GcrParser *self)
+{
+	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
+	return self->pv->parsed_desc;
+}
+
+GP11Attributes*
+gcr_parser_get_parsed_attributes (GcrParser *self)
+{
+	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
+	return self->pv->parsed_attrs;	
+}
+
+const gchar*
+gcr_parser_get_parsed_label (GcrParser *self)
+{
+	g_return_val_if_fail (GCR_IS_PARSER (self), NULL);
+	return self->pv->parsed_label;		
+}

Added: trunk/gcr/gcr-parser.h
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-parser.h	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,92 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2008 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __GCR_PARSER_H__
+#define __GCR_PARSER_H__
+
+#include <glib-object.h>
+
+#include "gcr-types.h"
+
+#define GCR_PARSER_ERROR              (gcr_parser_get_error_domain ())
+
+#define GCR_TYPE_PARSER               (gcr_parser_get_type ())
+#define GCR_PARSER(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_PARSER, GcrParser))
+#define GCR_PARSER_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_PARSER, GcrParserClass))
+#define GCR_IS_PARSER(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_PARSER))
+#define GCR_IS_PARSER_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_PARSER))
+#define GCR_PARSER_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_PARSER, GcrParserClass))
+
+typedef struct _GcrParser GcrParser;
+typedef struct _GcrParsedItem GcrParsedItem;
+typedef struct _GcrParserClass GcrParserClass;
+typedef struct _GcrParserPrivate GcrParserPrivate;
+
+struct _GcrParser {
+	GObject parent;
+	GcrParserPrivate *pv;
+};
+
+struct _GcrParserClass {
+	GObjectClass parent_class;
+    
+	/* signals --------------------------------------------------------- */
+    
+	/* A callback for each password needed */
+	gboolean (*authenticate) (GcrParser *self, gint count);
+	
+	void     (*parsed) (GcrParser *self);
+};
+
+GType               gcr_parser_get_type               (void);
+
+GQuark 	            gcr_parser_get_error_domain       (void) G_GNUC_CONST;
+
+GcrParser*          gcr_parser_new                    (void);
+
+gboolean            gcr_parser_format_enable          (GcrParser *self, 
+                                                       gint format);
+
+gboolean            gcr_parser_format_disable         (GcrParser *self, 
+                                                       gint format);
+
+gboolean            gcr_parser_format_supported       (GcrParser *self,
+                                                       gint format);
+
+gboolean            gcr_parser_parse_data             (GcrParser *self, 
+                                                       const guchar *data, 
+                                                       gsize n_data, 
+                                                       GError **err);
+
+gboolean            gcr_parser_parse_file             (GcrParser *self, 
+                                                       const gchar *filename, 
+                                                       GError **err);
+
+void                gcr_parser_add_password           (GcrParser *self,
+                                                       const gchar *password);
+
+const gchar*        gcr_parser_get_parsed_label       (GcrParser *self);
+
+const gchar*        gcr_parser_get_parsed_description (GcrParser *self);
+
+GP11Attributes*     gcr_parser_get_parsed_attributes  (GcrParser *self);
+
+#endif /* __GCR_PARSER_H__ */

Added: trunk/gcr/gcr-types.h
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr-types.h	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,45 @@
+#ifndef GCRTYPES_H_
+#define GCRTYPES_H_
+
+enum {
+	GCR_PARSE_FAILURE = -1,
+	GCR_PARSE_UNRECOGNIZED = 1,
+	GCR_PARSE_CANCELLED = 2,
+	GCR_PARSE_LOCKED = 3
+};
+
+enum {
+	GCR_FORMAT_INVALID = 0,
+	
+	GCR_FORMAT_DER_PRIVATE_KEY = 100,
+	GCR_FORMAT_DER_PRIVATE_KEY_RSA,
+	GCR_FORMAT_DER_PRIVATE_KEY_DSA,
+	
+	GCR_FORMAT_DER_CERTIFICATE_X509 = 200,
+
+	GCR_FORMAT_DER_PKCS7 = 300,
+	
+	GCR_FORMAT_DER_PKCS8 = 400,
+	GCR_FORMAT_DER_PKCS8_PLAIN,
+	GCR_FORMAT_DER_PKCS8_ENCRYPTED,
+	
+	GCR_FORMAT_DER_PKCS12 = 500,
+	
+	GCR_FORMAT_PEM = 1000,
+	GCR_FORMAT_PEM_PRIVATE_KEY_RSA,
+	GCR_FORMAT_PEM_PRIVATE_KEY_DSA,
+	GCR_FORMAT_PEM_CERTIFICATE_X509,
+	GCR_FORMAT_PEM_PKCS7,
+	GCR_FORMAT_PEM_PKCS8_PLAIN,
+	GCR_FORMAT_PEM_PKCS8_ENCRYPTED,
+	GCR_FORMAT_PEM_PKCS12
+};
+
+#ifndef GP11_H
+
+/* Forward declare some of the GP11 objects */
+typedef struct _GP11Attributes GP11Attributes;
+
+#endif /* GP11_H */
+
+#endif /* GCRTYPES_H_ */

Added: trunk/gcr/gcr.pc.in
==============================================================================
--- (empty file)
+++ trunk/gcr/gcr.pc.in	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,14 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+datarootdir= datarootdir@
+datadir= datadir@
+sysconfdir= sysconfdir@
+
+Name: gp11
+Description: GObject bindings for PKCS#11
+Version: @VERSION@
+Requires: glib-2.0
+Libs: -L${libdir} -lgp11
+Cflags: -I${includedir}/gp11

Added: trunk/gcr/template/gcr-xxx.c
==============================================================================
--- (empty file)
+++ trunk/gcr/template/gcr-xxx.c	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,146 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2008 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#include "config.h"
+
+#include "gcr-xxx.h"
+
+enum {
+	PROP_0,
+	PROP_XXX
+};
+
+enum {
+	SIGNAL,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+
+struct _GcrXxxPrivate {
+};
+
+G_DEFINE_TYPE (GcrXxx, gcr_xxx, G_TYPE_OBJECT);
+
+/* -----------------------------------------------------------------------------
+ * INTERNAL 
+ */
+
+/* -----------------------------------------------------------------------------
+ * OBJECT 
+ */
+
+
+static GObject* 
+gcr_xxx_constructor (GType type, guint n_props, GObjectConstructParam *props) 
+{
+	GcrXxx *self = GCR_XXX (G_OBJECT_CLASS (gcr_xxx_parent_class)->constructor(type, n_props, props));
+	g_return_val_if_fail (self, NULL);	
+
+
+	
+	return G_OBJECT (self);
+}
+
+static void
+gcr_xxx_init (GcrXxx *self)
+{
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCR_TYPE_XXX, GcrXxxPrivate);
+}
+
+static void
+gcr_xxx_dispose (GObject *obj)
+{
+	GcrXxx *self = GCR_XXX (obj);
+    
+	G_OBJECT_CLASS (gcr_xxx_parent_class)->dispose (obj);
+}
+
+static void
+gcr_xxx_finalize (GObject *obj)
+{
+	GcrXxx *self = GCR_XXX (obj);
+
+	G_OBJECT_CLASS (gcr_xxx_parent_class)->finalize (obj);
+}
+
+static void
+gcr_xxx_set_property (GObject *obj, guint prop_id, const GValue *value, 
+                           GParamSpec *pspec)
+{
+	GcrXxx *self = GCR_XXX (obj);
+	
+	switch (prop_id) {
+	case PROP_XXX:
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gcr_xxx_get_property (GObject *obj, guint prop_id, GValue *value, 
+                           GParamSpec *pspec)
+{
+	GcrXxx *self = GCR_XXX (obj);
+	
+	switch (prop_id) {
+	case PROP_XXX:
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+gcr_xxx_class_init (GcrXxxClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+    
+	gobject_class->constructor = gcr_xxx_constructor;
+	gobject_class->dispose = gcr_xxx_dispose;
+	gobject_class->finalize = gcr_xxx_finalize;
+	gobject_class->set_property = gcr_xxx_set_property;
+	gobject_class->get_property = gcr_xxx_get_property;
+    
+	g_type_class_add_private (gobject_class, sizeof (GcrXxxPrivate));
+	
+	g_object_class_install_property (gobject_class, PROP_XXX,
+	           g_param_spec_pointer ("xxx", "Xxx", "Xxx.", G_PARAM_READWRITE));
+    
+	signals[SIGNAL] = g_signal_new ("signal", GCR_TYPE_XXX, 
+	                                G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GcrXxxClass, signal),
+	                                NULL, NULL, g_cclosure_marshal_VOID__OBJECT, 
+	                                G_TYPE_NONE, 0);
+}
+
+/* -----------------------------------------------------------------------------
+ * PUBLIC 
+ */
+
+GcrXxx*
+gcr_xxx_new (void)
+{
+	return g_object_new (GCR_TYPE_XXX, NULL);
+}

Added: trunk/gcr/template/gcr-xxx.h
==============================================================================
--- (empty file)
+++ trunk/gcr/template/gcr-xxx.h	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,55 @@
+/* 
+ * gnome-keyring
+ * 
+ * Copyright (C) 2008 Stefan Walter
+ * 
+ * This program is free software; you can redistribute it and/or modify 
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *  
+ * This program 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
+ * Lesser General Public License for more details.
+ *  
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.  
+ */
+
+#ifndef __GCR_XXX_H__
+#define __GCR_XXX_H__
+
+#include <glib-object.h>
+
+#define GCR_TYPE_XXX               (gcr_xxx_get_type ())
+#define GCR_XXX(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCR_TYPE_XXX, GcrXxx))
+#define GCR_XXX_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_XXX, GcrXxxClass))
+#define GCR_IS_XXX(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCR_TYPE_XXX))
+#define GCR_IS_XXX_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_XXX))
+#define GCR_XXX_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_XXX, GcrXxxClass))
+
+typedef struct _GcrXxx GcrXxx;
+typedef struct _GcrXxxClass GcrXxxClass;
+typedef struct _GcrXxxPrivate GcrXxxPrivate;
+
+struct _GcrXxx {
+	GObject parent;
+	GcrXxxPrivate *pv;
+};
+
+struct _GcrXxxClass {
+	GObjectClass parent_class;
+    
+	/* signals --------------------------------------------------------- */
+    
+	void (*signal) (GcrXxx *self);
+};
+
+GType               gcr_xxx_get_type               (void);
+
+GcrXxx*             gcr_xxx_new                    (void);
+
+#endif /* __GCR_XXX_H__ */

Added: trunk/gcr/tests/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/gcr/tests/Makefile.am	Sun Jan 18 22:24:09 2009
@@ -0,0 +1,13 @@
+
+# Test files should be listed in order they need to run
+UNIT_AUTO = \
+	unit-test-parser.c
+
+UNIT_PROMPT = 
+
+UNIT_LIBS =  \
+	$(top_builddir)/gcr/libgcr.la \
+	$(top_builddir)/egg/libegg.la \
+	$(top_builddir)/gp11/libgp11.la
+
+include $(top_srcdir)/tests/gtest.make

Copied: trunk/gcr/tests/unit-test-parser.c (from r1461, /trunk/daemon/pkix/tests/unit-test-pkix-parser.c)
==============================================================================
--- /trunk/daemon/pkix/tests/unit-test-pkix-parser.c	(original)
+++ trunk/gcr/tests/unit-test-parser.c	Sun Jan 18 22:24:09 2009
@@ -25,11 +25,9 @@
 
 #include "run-auto-test.h"
 
-#include "common/gkr-location.h"
-#include "common/gkr-crypto.h"
 #include "egg/egg-secure-memory.h"
 
-#include "pkix/gkr-pkix-parser.h"
+#include "gcr/gcr-parser.h"
 
 #include <glib.h>
 #include <gcrypt.h>
@@ -52,263 +50,87 @@
  * Tests be run in the order specified here.
  */
 
-static GkrPkixParser *parser = NULL;
+static GcrParser *parser = NULL;
+static const gchar* filedesc = NULL;
 
-static GQuark last_type_parsed = 0;
-static gcry_sexp_t last_sexp_parsed = NULL;
-static ASN1_TYPE last_asn1_parsed = NULL;
-static guint n_parsed = 0;
-
-static CuTest *the_cu = NULL;
-
-static gboolean
-parsed_partial (GkrPkixParser *parser, GQuark location, gkrconstid digest, 
-                GQuark type, gpointer user_data)
+static void
+parsed_item (GcrParser *par, gpointer user_data)
 {
-	CuTest *cu = the_cu;
-	g_assert (cu);
-		
-	CuAssert (cu, "location is empty", location != 0);
-	CuAssert (cu, "location is invalid", gkr_location_to_path (location) != NULL);
-	CuAssert (cu, "digest is empty", digest != NULL);
-	CuAssert (cu, "type is invalid", type != 0);
+	GP11Attributes *attrs;
+	const gchar *description;
+	const gchar *label;
 	
-	g_print ("parsed partial at: %s\n", g_quark_to_string (location));
-	last_sexp_parsed = NULL;
-	last_type_parsed = type;
-	++n_parsed;
+	g_assert (GCR_IS_PARSER (par));
+	g_assert (par == parser);
+	g_assert (par == user_data);
 	
-	return TRUE;
-}
-
-static gboolean
-parsed_sexp (GkrPkixParser *parser, GQuark location, gkrconstid digest, 
-             GQuark type, gcry_sexp_t sexp, gpointer user_data)
-{
-	CuTest *cu = the_cu;
-	g_assert (cu);
-
-	CuAssert (cu, "location is empty", location != 0);
-	CuAssert (cu, "location is invalid", gkr_location_to_path (location) != NULL);
-	CuAssert (cu, "digest is empty", digest != NULL);
-	CuAssert (cu, "type is invalid", type != 0);
-	CuAssert (cu, "sexp is invalid", sexp != NULL);
-
-	g_print ("parsed sexp at: %s\n", g_quark_to_string (location));
-		
-	last_sexp_parsed = sexp;
-	last_type_parsed = type;
-	++n_parsed;
-	
-	return TRUE;
-}
-
-static gboolean
-parsed_asn1 (GkrPkixParser *parser, GQuark location, gkrconstid digest,
-             GQuark type, ASN1_TYPE asn1, gpointer user_data)
-{
-	CuTest *cu = the_cu;
-	g_assert (cu);
-
-	CuAssert (cu, "location is empty", location != 0);
-	CuAssert (cu, "location is invalid", gkr_location_to_path (location) != NULL);
-	CuAssert (cu, "digest is empty", digest != NULL);
-	CuAssert (cu, "type is invalid", type != 0);
-	CuAssert (cu, "asn1 is invalid", asn1 != NULL);
-
-	g_print ("parsed asn1 at: %s\n", g_quark_to_string (location));
-		
-	last_asn1_parsed = asn1;
-	last_type_parsed = type;
-	++n_parsed;
+	attrs = gcr_parser_get_parsed_attributes (parser);
+	description = gcr_parser_get_parsed_description (parser);
+	label = gcr_parser_get_parsed_label (parser);
 	
-	return TRUE;
+	g_print ("parsed %s '%s' at: %s\n", description, label, filedesc);
 }
 
 static gboolean
-ask_password (GkrPkixParser *parser, GQuark loc, gkrconstid digest, 
-              GQuark type, const gchar *details, gint *state, 
-              gchar **password, gpointer user_data) 
+authenticate (GcrParser *par, gint state, gpointer user_data) 
 {
-	CuTest *cu = the_cu;
-	gchar *msg;
-	gint st;
-	
-	g_assert (cu);
-	CuAssert (cu, "state is null", state != NULL);
-	CuAssert (cu, "state is bad", *state >= 0 && *state < 3);
-
-	st = *state;
-	(*state)++;
+	g_assert (GCR_IS_PARSER (par));
+	g_assert (par == parser);
+	g_assert (par == user_data);
 
-	CuAssert (cu, "location is empty", loc != 0);
-	CuAssert (cu, "details is null", details != NULL);
-	
-	/* Return "", null, and "booo" in that order */
-	switch (st) {
+	switch (state) {
 	case 0:
-		*password = egg_secure_strdup ("");
-		return TRUE;
-	case 1:
-		*password = NULL;
-		return TRUE;
-	case 2:
-		/* Most of our test encrypted stuff use this password */
-		g_print ("getting password 'booo' for: %s\n", details); 	
-		*password = egg_secure_strdup ("booo");
+		gcr_parser_add_password (parser, "booo");
 		return TRUE;
 	default:
-		msg = g_strdup_printf ("decryption didn't work for: %s", g_quark_to_string (loc));
-		CuAssert (cu, msg, FALSE);
-		return FALSE;
+		g_printerr ("decryption didn't work for: %s", filedesc);
+		g_assert (FALSE);
 	};
-}
+} 
 
-static void
-read_file (CuTest *cu, const gchar *filename, GQuark *location, guchar **contents, gsize *len)
+DEFINE_SETUP(parser)
 {
-	gchar *path;
-	gboolean ret;
-	
-	the_cu = cu;
-	
-	path = g_build_filename (g_get_current_dir (), "test-data", filename, NULL);
-	*location = gkr_location_from_path (path);
-	CuAssert (cu, "location is empty", *location != 0);
-	
-	ret = g_file_get_contents (path, (gchar**)contents, len, NULL);
-	CuAssert (cu, "couldn't read in file", ret);
-	
-	g_free (path);
+	parser = gcr_parser_new ();
+	g_signal_connect (parser, "parsed", G_CALLBACK (parsed_item), parser);
+	g_signal_connect (parser, "authenticate", G_CALLBACK (authenticate), parser);
 }
-	 
 
-void unit_test_start_parser (CuTest *cu)
+DEFINE_TEARDOWN(parser)
 {
-	parser = gkr_pkix_parser_new (FALSE);
-	g_signal_connect (parser, "parsed-partial", G_CALLBACK (parsed_partial), NULL);
-	g_signal_connect (parser, "parsed-sexp", G_CALLBACK (parsed_sexp), NULL);
-	g_signal_connect (parser, "parsed-asn1", G_CALLBACK (parsed_asn1), NULL);
-	g_signal_connect (parser, "ask-password", G_CALLBACK (ask_password), NULL);
+	g_object_unref (parser);
+	parser = NULL;
 }
 
-void unit_test_pkix_parse_der_keys (CuTest* cu)
+DEFINE_TEST(parse_all)
 {
 	guchar *contents;
-	GkrPkixResult result;
-	GQuark location;
-	gsize len;
-	
-	the_cu = cu;
-
-	/* First an RSA key */
-	read_file (cu, "der-rsa-1024.key", &location, &contents, &len);
-	
-	last_sexp_parsed = NULL;
-	result = gkr_pkix_parser_der_private_key (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse RSA key", result == GKR_PKIX_SUCCESS);
-	CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
-	
-	gkr_crypto_sexp_dump (last_sexp_parsed);
-
-	/* Now a DSA key */	
-	read_file (cu, "der-dsa-1024.key", &location, &contents, &len);
-	
-	last_sexp_parsed = NULL;
-	result = gkr_pkix_parser_der_private_key (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse DSA key", result == GKR_PKIX_SUCCESS);
-	CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
-	
-	gkr_crypto_sexp_dump (last_sexp_parsed);
-}
-
-void unit_test_pkix_parse_der_pkcs8 (CuTest* cu)
-{
-	guchar *contents;
-	GkrPkixResult result;
-	GQuark location;
-	gsize len;
-	
-	the_cu = cu;
-
-	/* First an DSA key */
-	read_file (cu, "der-pkcs8-dsa.key", &location, &contents, &len);
-	
-	last_sexp_parsed = NULL;
-	result = gkr_pkix_parser_der_pkcs8_plain (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse PKCS8 key", result == GKR_PKIX_SUCCESS);
-	CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
-	
-	gkr_crypto_sexp_dump (last_sexp_parsed);
-	
-	/* Now an encrypted key */
-	read_file (cu, "der-pkcs8-encrypted-pkcs5.key", &location, &contents, &len);
-	
-	last_sexp_parsed = NULL;
-	result = gkr_pkix_parser_der_pkcs8_encrypted (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse PKCS8 key", result == GKR_PKIX_SUCCESS);
-	CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
-	
-	gkr_crypto_sexp_dump (last_sexp_parsed);	
-}
-
-void unit_test_pkix_parse_pem (CuTest *cu)
-{
-	guchar *contents;
-	GkrPkixResult result;
-	GQuark location;
-	gsize len;
-	
-	the_cu = cu;
-
-	/* First an RSA key */
-	read_file (cu, "pem-dsa-1024.key", &location, &contents, &len);
-	
-	n_parsed = 0;
-	result = gkr_pkix_parser_pem (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse PEM data", result == GKR_PKIX_SUCCESS);
-
-	CuAssert (cu, "invalid number of items parsed", n_parsed == 1);
-	CuAssert (cu, "invalid type of data parsed", last_sexp_parsed != NULL);
-	
-	gkr_crypto_sexp_dump (last_sexp_parsed);
-}
-
-void unit_test_pkix_parse_all (CuTest *cu)
-{
-	gchar *path, *filepath, *msg;
-	guchar *contents;
 	GError *err = NULL;
 	gboolean result;
 	const gchar *filename;
-	GQuark location;
 	gsize len;
 	GDir *dir;
 	
-	the_cu = cu;
-	path = g_build_filename (g_get_current_dir (), "test-data", NULL);
-	
-	dir = g_dir_open (path, 0, NULL);
-	CuAssert (cu, "couldn't open directory", dir != NULL); 
+	dir = g_dir_open ("test-data", 0, NULL);
+	g_assert (dir);
 
-	while (dir) {
+	for (;;) {
 		filename = g_dir_read_name (dir);
 		if (!filename)
 			break;
-			
-		filepath = g_build_filename (path, filename, NULL);
-		if (!g_file_test (filepath, G_FILE_TEST_IS_REGULAR))
+		if (filename[0] == '.')
 			continue;
 		
-		read_file (cu, filename, &location, &contents, &len);
+		filedesc = filename;
+		contents = test_read_testdata (filename, &len);
 		
-		result = gkr_pkix_parser_parse (parser, location, contents, len, &err);
+		result = gcr_parser_parse_data (parser, contents, len, &err);
 		if (!result) { 
-			msg = g_strdup_printf ("couldn't parse file data: %s: %s", 
-			                       filename, err && err->message ? err->message : "");
+			g_warning ("couldn't parse file data: %s: %s", 
+			           filename, err && err->message ? err->message : "");
 			g_error_free (err);
-			err = NULL;
-			CuAssert (cu, msg, FALSE);
+			g_assert (FALSE);
 		}
 	}
+	
+	g_dir_close (dir);
 }

Modified: trunk/gp11/gp11.h
==============================================================================
--- trunk/gp11/gp11.h	(original)
+++ trunk/gp11/gp11.h	Sun Jan 18 22:24:09 2009
@@ -21,8 +21,8 @@
    Author: Stef Walter <nielsen memberwebs com>
 */
 
-#ifndef GP11_H_
-#define GP11_H_
+#ifndef GP11_H
+#define GP11_H
 
 #include <glib.h>
 #include <glib-object.h>
@@ -1431,4 +1431,4 @@
 
 G_END_DECLS
 
-#endif /*GP11_H_*/
+#endif /*GP11_H*/

Modified: trunk/pkcs11/gck/Makefile.am
==============================================================================
--- trunk/pkcs11/gck/Makefile.am	(original)
+++ trunk/pkcs11/gck/Makefile.am	Sun Jan 18 22:24:09 2009
@@ -24,8 +24,6 @@
 	gck-data-asn1.c gck-data-asn1.h \
 	gck-data-der.c gck-data-der.h \
 	gck-data-file.c gck-data-file.h \
-	gck-data-openssl.c gck-data-openssl.h \
-	gck-data-pem.c gck-data-pem.h \
 	gck-data-types.h \
 	gck-factory.c gck-factory.h \
 	gck-file-tracker.c gck-file-tracker.h \

Modified: trunk/pkcs11/gck/gck-crypto.c
==============================================================================
--- trunk/pkcs11/gck/gck-crypto.c	(original)
+++ trunk/pkcs11/gck/gck-crypto.c	Sun Jan 18 22:24:09 2009
@@ -977,520 +977,6 @@
 	return unpad_rsa_pkcs1 (0x02, bits, padded, n_padded, n_raw);
 }
 
-/* -----------------------------------------------------------------------------
- * PASSWORD TO KEY/IV
- */
-
-gboolean
-gck_crypto_symkey_generate_simple (int cipher_algo, int hash_algo, 
-                                   const gchar *password, gssize n_password, 
-                                   const guchar *salt, gsize n_salt, int iterations, 
-                                   guchar **key, guchar **iv)
-{
-	gcry_md_hd_t mdh;
-	gcry_error_t gcry;
-	guchar *digest;
-	guchar *digested;
-	guint n_digest;
-	gint pass, i;
-	gint needed_iv, needed_key;
-	guchar *at_iv, *at_key;
-
-	g_assert (cipher_algo);
-	g_assert (hash_algo);
-
-	g_return_val_if_fail (iterations >= 1, FALSE);
-	
-	if (!password)
-		n_password = 0;
-	if (n_password == -1)
-		n_password = strlen (password);
-	
-	/* 
-	 * If cipher algo needs more bytes than hash algo has available
-	 * then the entire hashing process is done again (with the previous
-	 * hash bytes as extra input), and so on until satisfied.
-	 */ 
-	
-	needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
-	
-	gcry = gcry_md_open (&mdh, hash_algo, 0);
-	if (gcry) {
-		g_warning ("couldn't create '%s' hash context: %s", 
-			   gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
-		return FALSE;
-	}
-
-	n_digest = gcry_md_get_algo_dlen (hash_algo);
-	g_return_val_if_fail (n_digest > 0, FALSE);
-	
-	digest = gcry_calloc_secure (n_digest, 1);
-	g_return_val_if_fail (digest, FALSE);
-	if (key) {
-		*key = gcry_calloc_secure (needed_key, 1);
-		g_return_val_if_fail (*key, FALSE);
-	}
-	if (iv) 
-		*iv = g_new0 (guchar, needed_iv);
-
-	at_key = key ? *key : NULL;
-	at_iv = iv ? *iv : NULL;
-
-	for (pass = 0; TRUE; ++pass) {
-		gcry_md_reset (mdh);
-		
-		/* Hash in the previous buffer on later passes */
-		if (pass > 0)
-			gcry_md_write (mdh, digest, n_digest);
-
-		if (password)
-			gcry_md_write (mdh, password, n_password);
-		if (salt && n_salt)
-			gcry_md_write (mdh, salt, n_salt);
-		gcry_md_final (mdh);
-		digested = gcry_md_read (mdh, 0);
-		g_return_val_if_fail (digested, FALSE);
-		memcpy (digest, digested, n_digest);
-		
-		for (i = 1; i < iterations; ++i) {
-			gcry_md_reset (mdh);
-			gcry_md_write (mdh, digest, n_digest);
-			gcry_md_final (mdh);
-			digested = gcry_md_read (mdh, 0);
-			g_return_val_if_fail (digested, FALSE);
-			memcpy (digest, digested, n_digest);
-		}
-		
-		/* Copy as much as possible into the destinations */
-		i = 0; 
-		while (needed_key && i < n_digest) {
-			if (at_key)
-				*(at_key++) = digest[i];
-			needed_key--;
-			i++;
-		}
-		while (needed_iv && i < n_digest) {
-			if (at_iv) 
-				*(at_iv++) = digest[i];
-			needed_iv--;
-			i++;
-		}
-		
-		if (needed_key == 0 && needed_iv == 0)
-			break;
-	}
-
-	gcry_free (digest);
-	gcry_md_close (mdh);
-	
-	return TRUE;
-}
-
-gboolean
-gck_crypto_symkey_generate_pbe (int cipher_algo, int hash_algo, const gchar *password, 
-                                gssize n_password, const guchar *salt, gsize n_salt, int iterations, 
-                                guchar **key, guchar **iv)
-{
-	gcry_md_hd_t mdh;
-	gcry_error_t gcry;
-	guchar *digest;
-	guchar *digested;
-	guint i, n_digest;
-	gint needed_iv, needed_key;
-
-	g_assert (cipher_algo);
-	g_assert (hash_algo);
-
-	g_return_val_if_fail (iterations >= 1, FALSE);
-	
-	if (!password)
-		n_password = 0;
-	if (n_password == -1)
-		n_password = strlen (password);
-	
-	/* 
-	 * We only do one pass here.
-	 * 
-	 * The key ends up as the first needed_key bytes of the hash buffer.
-	 * The iv ends up as the last needed_iv bytes of the hash buffer. 
-	 * 
-	 * The IV may overlap the key (which is stupid) if the wrong pair of 
-	 * hash/cipher algorithms are chosen.
-	 */ 
-
-	n_digest = gcry_md_get_algo_dlen (hash_algo);
-	g_return_val_if_fail (n_digest > 0, FALSE);
-	
-	needed_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	needed_iv = gcry_cipher_get_algo_blklen (cipher_algo);
-	if (needed_iv + needed_key > 16 || needed_iv + needed_key > n_digest) {
-		g_warning ("using PBE symkey generation with %s using an algorithm that needs " 
-		           "too many bytes of key and/or IV: %s",
-		           gcry_cipher_algo_name (hash_algo), 
-		           gcry_cipher_algo_name (cipher_algo));
-		return FALSE;
-	}
-	
-	gcry = gcry_md_open (&mdh, hash_algo, 0);
-	if (gcry) {
-		g_warning ("couldn't create '%s' hash context: %s", 
-			   gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
-		return FALSE;
-	}
-
-	digest = gcry_calloc_secure (n_digest, 1);
-	g_return_val_if_fail (digest, FALSE);
-	if (key) {
-		*key = gcry_calloc_secure (needed_key, 1);
-		g_return_val_if_fail (*key, FALSE);
-	}
-	if (iv) 
-		*iv = g_new0 (guchar, needed_iv);
-
-	if (password)
-		gcry_md_write (mdh, password, n_password);
-	if (salt && n_salt)
-		gcry_md_write (mdh, salt, n_salt);
-	gcry_md_final (mdh);
-	digested = gcry_md_read (mdh, 0);
-	g_return_val_if_fail (digested, FALSE);
-	memcpy (digest, digested, n_digest);
-		
-	for (i = 1; i < iterations; ++i)
-		gcry_md_hash_buffer (hash_algo, digest, digest, n_digest);
-	
-	/* The first x bytes are the key */
-	if (key) {
-		g_assert (needed_key <= n_digest);
-		memcpy (*key, digest, needed_key);
-	}
-	
-	/* The last 16 - x bytes are the iv */
-	if (iv) {
-		g_assert (needed_iv <= n_digest && n_digest >= 16);
-		memcpy (*iv, digest + (16 - needed_iv), needed_iv);
-	}
-		
-	gcry_free (digest);
-	gcry_md_close (mdh);
-	
-	return TRUE;	
-}
-
-static gboolean
-generate_pkcs12 (int hash_algo, int type, const gchar *utf8_password, 
-                 gssize n_password, const guchar *salt, gsize n_salt, 
-                 int iterations, guchar *output, gsize n_output)
-{
-	gcry_mpi_t num_b1, num_ij;
-	guchar *hash, *buf_i, *buf_b;
-	const gchar *end_password;
-	gcry_md_hd_t mdh;
-	const gchar *p2;
-	guchar *p;
-	gsize n_hash, i;
-	gunichar unich;
-	gcry_error_t gcry;
-	
-	num_b1 = num_ij = NULL;
-	
-	n_hash = gcry_md_get_algo_dlen (hash_algo);
-	g_return_val_if_fail (n_hash > 0, FALSE);
-	
-	if (!utf8_password)
-		n_password = 0;
-	if (n_password == -1) 
-		end_password = utf8_password + strlen (utf8_password);
-	else
-		end_password = utf8_password + n_password;
-	
-	gcry = gcry_md_open (&mdh, hash_algo, 0);
-	if (gcry) {
-		g_warning ("couldn't create '%s' hash context: %s", 
-		           gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
-		return FALSE;
-	}
-
-	/* Reqisition me a buffer */
-	hash = gcry_calloc_secure (n_hash, 1);
-	buf_i = gcry_calloc_secure (1, 128);
-	buf_b = gcry_calloc_secure (1, 64);
-	g_return_val_if_fail (hash && buf_i && buf_b, FALSE);
-		
-	/* Bring in the salt */
-	p = buf_i;
-	if (salt) {
-		for (i = 0; i < 64; ++i)
-			*(p++) = salt[i % n_salt];
-	} else {
-		memset (p, 0, 64);
-		p += 64;
-	}
-	
-	/* Bring in the password, as 16bits per character BMP string, ie: UCS2 */
-	if (utf8_password) {
-		p2 = utf8_password;
-		for (i = 0; i < 64; i += 2) {
-			
-			/* Get a character from the string */
-			if (p2 < end_password) {
-				unich = g_utf8_get_char (p2);
-				p2 = g_utf8_next_char (p2);
-
-			/* Get zero null terminator, and loop back to beginning */
-			} else {
-				unich = 0;
-				p2 = utf8_password;
-			}
-
-			/* Encode the bytes received */
-			*(p++) = (unich & 0xFF00) >> 8;
-			*(p++) = (unich & 0xFF);
-		}
-	} else {
-		memset (p, 0, 64);
-		p += 64;
-	}
-	
-	/* Hash and bash */
-	for (;;) {
-		gcry_md_reset (mdh);
-
-		/* Put in the PKCS#12 type of key */
-		for (i = 0; i < 64; ++i)
-			gcry_md_putc (mdh, type);
-			
-		/* Bring in the password */
-		gcry_md_write (mdh, buf_i, utf8_password ? 128 : 64);
-		
-		/* First iteration done */
-		memcpy (hash, gcry_md_read (mdh, hash_algo), n_hash);
-		
-		/* All the other iterations */
-		for (i = 1; i < iterations; i++)
-			gcry_md_hash_buffer (hash_algo, hash, hash, n_hash);
-		
-		/* Take out as much as we need */
-		for (i = 0; i < n_hash && n_output; ++i) {
-			*(output++) = hash[i];
-			--n_output;
-		}
-		
-		/* Is that enough generated keying material? */
-		if (!n_output)
-			break;
-			
-		/* Need more bytes, do some voodoo */
-		for (i = 0; i < 64; ++i)
-			buf_b[i] = hash[i % n_hash];
-		gcry = gcry_mpi_scan (&num_b1, GCRYMPI_FMT_USG, buf_b, 64, NULL);
-		g_return_val_if_fail (gcry == 0, FALSE);
-		gcry_mpi_add_ui (num_b1, num_b1, 1);
-		for (i = 0; i < 128; i += 64) {
-			gcry = gcry_mpi_scan (&num_ij, GCRYMPI_FMT_USG, buf_i + i, 64, NULL);
-			g_return_val_if_fail (gcry == 0, FALSE);
-			gcry_mpi_add (num_ij, num_ij, num_b1);
-			gcry_mpi_clear_highbit (num_ij, 64 * 8);
-			gcry = gcry_mpi_print (GCRYMPI_FMT_USG, buf_i + i, 64, NULL, num_ij);
-			g_return_val_if_fail (gcry == 0, FALSE);
-			gcry_mpi_release (num_ij);
-		}
-	}  
-	
-	gcry_free (buf_i);
-	gcry_free (buf_b);
-	gcry_free (hash);
-	gcry_mpi_release (num_b1);
-	gcry_md_close (mdh);
-	
-	return TRUE;
-}
-
-gboolean
-gck_crypto_symkey_generate_pkcs12 (int cipher_algo, int hash_algo, const gchar *password, 
-                                   gssize n_password, const guchar *salt, gsize n_salt,
-                                   int iterations, guchar **key, guchar **iv)
-{
-	gsize n_block, n_key;
-	gboolean ret = TRUE;
-	
-	g_return_val_if_fail (cipher_algo, FALSE);
-	g_return_val_if_fail (hash_algo, FALSE);
-	g_return_val_if_fail (iterations > 0, FALSE);
-	
-	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	n_block = gcry_cipher_get_algo_blklen (cipher_algo);
-	
-	if (password && !g_utf8_validate (password, n_password, NULL)) {
-		g_warning ("invalid non-UTF8 password");
-		g_return_val_if_reached (FALSE);
-	}
-	
-	if (key)
-		*key = NULL;
-	if (iv)
-		*iv = NULL;
-	
-	/* Generate us an key */
-	if (key) {
-		*key = gcry_calloc_secure (n_key, 1);
-		g_return_val_if_fail (*key != NULL, FALSE);
-		ret = generate_pkcs12 (hash_algo, 1, password, n_password, salt, n_salt, 
-		                       iterations, *key, n_key);
-	} 
-	
-	/* Generate us an iv */
-	if (ret && iv) {
-		if (n_block > 1) {
-			*iv = g_malloc (n_block);
-			ret = generate_pkcs12 (hash_algo, 2, password, n_password, salt, n_salt, 
-			                       iterations, *iv, n_block);
-		} else {
-			*iv = NULL;
-		}
-	}
-	
-	/* Cleanup in case of failure */
-	if (!ret) {
-		g_free (iv ? *iv : NULL);
-		gcry_free (key ? *key : NULL);
-	}
-	
-	return ret;
-}
-
-static gboolean
-generate_pbkdf2 (int hash_algo, const gchar *password, gsize n_password,
-		 const guchar *salt, gsize n_salt, guint iterations,
-		 guchar *output, gsize n_output)
-{
-	gcry_md_hd_t mdh;
-	guint u, l, r, i, k;
-	gcry_error_t gcry;
-	guchar *U, *T, *buf;
-	gsize n_buf, n_hash;
-	
-	g_return_val_if_fail (hash_algo > 0, FALSE);
-	g_return_val_if_fail (iterations > 0, FALSE);
-	g_return_val_if_fail (n_output > 0, FALSE);
-	g_return_val_if_fail (n_output < G_MAXUINT32, FALSE);
-
-	n_hash = gcry_md_get_algo_dlen (hash_algo);
-	g_return_val_if_fail (n_hash > 0, FALSE);
-	
-	gcry = gcry_md_open (&mdh, hash_algo, GCRY_MD_FLAG_HMAC);
-	if (gcry != 0) {
-		g_warning ("couldn't create '%s' hash context: %s", 
-		           gcry_md_algo_name (hash_algo), gcry_strerror (gcry));
-		return FALSE;
-	}
-
-	/* Get us a temporary buffers */
-	T = gcry_calloc_secure (n_hash, 1);
-	U = gcry_calloc_secure (n_hash, 1);
-	n_buf = n_salt + 4;
-	buf = gcry_calloc_secure (n_buf, 1);
-	g_return_val_if_fail (buf && T && U, FALSE);
-
-	/* n_hash blocks in output, rounding up */
-	l = ((n_output - 1) / n_hash) + 1;
-	
-	/* number of bytes in last, rounded up, n_hash block */
-	r = n_output - (l - 1) * n_hash;
-	
-	memcpy (buf, salt, n_salt);
-	for (i = 1; i <= l; i++) {
-		memset (T, 0, n_hash);
-		for (u = 1; u <= iterations; u++) {
-			gcry_md_reset (mdh);
-
-			gcry = gcry_md_setkey (mdh, password, n_password);
-			g_return_val_if_fail (gcry == 0, FALSE);
-			
-			/* For first iteration on each block add 4 extra bytes */
-			if (u == 1) {
-				buf[n_salt + 0] = (i & 0xff000000) >> 24;
-				buf[n_salt + 1] = (i & 0x00ff0000) >> 16;
-				buf[n_salt + 2] = (i & 0x0000ff00) >> 8;
-				buf[n_salt + 3] = (i & 0x000000ff) >> 0;
-				
-				gcry_md_write (mdh, buf, n_buf);
-		
-			/* Other iterations, any block */
-			} else {
-				gcry_md_write (mdh, U, n_hash);
-			}
-			
-			memcpy (U, gcry_md_read (mdh, hash_algo), n_hash);
-
-			for (k = 0; k < n_hash; k++)
-				T[k] ^= U[k];
-		}
-
-		memcpy (output + (i - 1) * n_hash, T, i == l ? r : n_hash);
-	}
-	
-	gcry_free (T);
-	gcry_free (U);
-	gcry_free (buf);
-	gcry_md_close (mdh);
-	return TRUE;
-}
-
-gboolean
-gck_crypto_symkey_generate_pbkdf2 (int cipher_algo, int hash_algo, 
-                                   const gchar *password, gssize n_password, 
-                                   const guchar *salt, gsize n_salt, int iterations, 
-                                   guchar **key, guchar **iv)
-{
-	gsize n_key, n_block;
-	gboolean ret = TRUE;
-	
-	g_return_val_if_fail (hash_algo, FALSE);
-	g_return_val_if_fail (cipher_algo, FALSE);
-	g_return_val_if_fail (iterations > 0, FALSE);
-	
-	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	n_block = gcry_cipher_get_algo_blklen (cipher_algo);
-	
-	if (key)
-		*key = NULL;
-	if (iv)
-		*iv = NULL;
-	
-	if (!password)
-		n_password = 0;
-	if (n_password == -1)
-		n_password = strlen (password);
-	
-	/* Generate us an key */
-	if (key) {
-		*key = gcry_calloc_secure (n_key, 1);
-		g_return_val_if_fail (*key != NULL, FALSE);
-		ret = generate_pbkdf2 (hash_algo, password, n_password, salt, n_salt, 
-		                       iterations, *key, n_key);
-	} 
-	
-	/* Generate us an iv */
-	if (ret && iv) {
-		if (n_block > 1) {
-			*iv = g_malloc (n_block);
-			gcry_create_nonce (*iv, n_block);
-		} else {
-			*iv = NULL;
-		}
-	}
-	
-	/* Cleanup in case of failure */
-	if (!ret) {
-		g_free (iv ? *iv : NULL);
-		gcry_free (key ? *key : NULL);
-	}
-	
-	return ret;
-}
-
 /* --------------------------------------------------------------------------
  * INITIALIZATION
  */

Modified: trunk/pkcs11/gck/gck-crypto.h
==============================================================================
--- trunk/pkcs11/gck/gck-crypto.h	(original)
+++ trunk/pkcs11/gck/gck-crypto.h	Sun Jan 18 22:24:09 2009
@@ -159,44 +159,4 @@
                                                                         gsize n_padded, 
                                                                         gsize *n_raw);
 
-gboolean                 gck_crypto_symkey_generate_simple             (int cipher_algo, 
-                                                                        int hash_algo, 
-                                                                        const gchar *password, 
-                                                                        gssize n_password,
-                                                                        const guchar *salt, 
-                                                                        gsize n_salt, 
-                                                                        int iterations, 
-                                                                        guchar **key, 
-                                                                        guchar **iv);
-
-gboolean                 gck_crypto_symkey_generate_pbe                (int cipher_algo, 
-                                                                        int hash_algo, 
-                                                                        const gchar *password,
-                                                                        gssize n_password,
-                                                                        const guchar *salt, 
-                                                                        gsize n_salt, 
-                                                                        int iterations, 
-                                                                        guchar **key, 
-                                                                        guchar **iv);
-
-gboolean                 gck_crypto_symkey_generate_pkcs12             (int cipher_algo, 
-                                                                        int hash_algo, 
-                                                                        const gchar *password,
-                                                                        gssize n_password,
-                                                                        const guchar *salt, 
-                                                                        gsize n_salt,
-                                                                        int iterations, 
-									guchar **key, 
-									guchar **iv);
-
-gboolean                 gck_crypto_symkey_generate_pbkdf2             (int cipher_algo, 
-                                                                        int hash_algo, 
-                                                                        const gchar *password,
-                                                                        gssize n_password,
-                                                                        const guchar *salt, 
-                                                                        gsize n_salt, 
-                                                                        int iterations, 
-                                                                        guchar **key, 
-                                                                        guchar **iv);
-
 #endif /* GCKCRYPTO_H_ */

Modified: trunk/pkcs11/gck/gck-data-der.c
==============================================================================
--- trunk/pkcs11/gck/gck-data-der.c	(original)
+++ trunk/pkcs11/gck/gck-data-der.c	Sun Jan 18 22:24:09 2009
@@ -29,6 +29,7 @@
 #include "gck-data-types.h"
 
 #include "egg/egg-secure-memory.h"
+#include "egg/egg-symkey.h"
 
 #include <glib.h>
 #include <gcrypt.h>
@@ -40,27 +41,7 @@
 
 static GQuark OID_PKIX1_RSA;
 static GQuark OID_PKIX1_DSA;
-
-static GQuark OID_PBE_MD2_DES_CBC;
-static GQuark OID_PBE_MD5_DES_CBC;
-static GQuark OID_PBE_MD2_RC2_CBC;
-static GQuark OID_PBE_MD5_RC2_CBC;
-static GQuark OID_PBE_SHA1_DES_CBC;
-static GQuark OID_PBE_SHA1_RC2_CBC;
-static GQuark OID_PBES2;
-static GQuark OID_PBKDF2;
-
-static GQuark OID_DES_CBC;
-static GQuark OID_DES_RC2_CBC;
-static GQuark OID_DES_EDE3_CBC;
-static GQuark OID_DES_RC5_CBC;
-
-static GQuark OID_PKCS12_PBE_ARCFOUR_SHA1;
-static GQuark OID_PKCS12_PBE_RC4_40_SHA1;
 static GQuark OID_PKCS12_PBE_3DES_SHA1;
-static GQuark OID_PKCS12_PBE_2DES_SHA1;
-static GQuark OID_PKCS12_PBE_RC2_128_SHA1;
-static GQuark OID_PKCS12_PBE_RC2_40_SHA1;
 
 static void
 init_quarks (void)
@@ -74,29 +55,7 @@
 
 		QUARK (OID_PKIX1_RSA, "1.2.840.113549.1.1.1");
 		QUARK (OID_PKIX1_DSA, "1.2.840.10040.4.1");
-
-		QUARK (OID_PBE_MD2_DES_CBC, "1.2.840.113549.1.5.1");
-		QUARK (OID_PBE_MD5_DES_CBC, "1.2.840.113549.1.5.3");
-		QUARK (OID_PBE_MD2_RC2_CBC, "1.2.840.113549.1.5.4");
-		QUARK (OID_PBE_MD5_RC2_CBC, "1.2.840.113549.1.5.6");
-		QUARK (OID_PBE_SHA1_DES_CBC, "1.2.840.113549.1.5.10");
-		QUARK (OID_PBE_SHA1_RC2_CBC, "1.2.840.113549.1.5.11");
-		
-		QUARK (OID_PBES2, "1.2.840.113549.1.5.13");
-		
-		QUARK (OID_PBKDF2, "1.2.840.113549.1.5.12");
-		
-		QUARK (OID_DES_CBC, "1.3.14.3.2.7");
-		QUARK (OID_DES_RC2_CBC, "1.2.840.113549.3.2");
-		QUARK (OID_DES_EDE3_CBC, "1.2.840.113549.3.7");
-		QUARK (OID_DES_RC5_CBC, "1.2.840.113549.3.9");
-		
-		QUARK (OID_PKCS12_PBE_ARCFOUR_SHA1, "1.2.840.113549.1.12.1.1");
-		QUARK (OID_PKCS12_PBE_RC4_40_SHA1, "1.2.840.113549.1.12.1.2");
 		QUARK (OID_PKCS12_PBE_3DES_SHA1, "1.2.840.113549.1.12.1.3");
-		QUARK (OID_PKCS12_PBE_2DES_SHA1, "1.2.840.113549.1.12.1.4");
-		QUARK (OID_PKCS12_PBE_RC2_128_SHA1, "1.2.840.113549.1.12.1.5");
-		QUARK (OID_PKCS12_PBE_RC2_40_SHA1, "1.2.840.113549.1.12.1.6");
 		
 		#undef QUARK
 		
@@ -638,7 +597,7 @@
 	/* 
 	 * Parse the encryption stuff into a cipher. 
 	 */
-	r = gck_data_der_read_cipher (scheme, password, n_password, params, n_params, &cih);
+	r = egg_symkey_read_cipher (scheme, password, n_password, params, n_params, &cih);
 	if (r == GCK_DATA_UNRECOGNIZED) {
 		ret = GCK_DATA_FAILURE;
 		goto done;
@@ -1031,7 +990,7 @@
 	*n_block = gcry_cipher_get_algo_blklen (GCRY_MD_SHA1);
 	g_return_val_if_fail (n_key && *n_block, NULL);
 		
-	if (!gck_crypto_symkey_generate_pkcs12 (GCRY_CIPHER_3DES, GCRY_MD_SHA1, 
+	if (!egg_symkey_generate_pkcs12 (GCRY_CIPHER_3DES, GCRY_MD_SHA1, 
 	                                        password, n_password, salt, 
 	                                        sizeof (salt), iterations, &key, &iv))
 		g_return_val_if_reached (NULL);
@@ -1322,437 +1281,3 @@
 	
 	return egg_asn1_encode (asn1, "", n_data, NULL);
 }
-
-/* -----------------------------------------------------------------------------
- * CIPHER/KEY DESCRIPTIONS 
- */
- 
-GckDataResult
-gck_data_der_read_cipher (GQuark oid_scheme, const gchar *password, gsize n_password,
-                          const guchar *data, gsize n_data, gcry_cipher_hd_t *cih)
-{
-	GckDataResult ret = GCK_DATA_UNRECOGNIZED;
-	
-	g_return_val_if_fail (oid_scheme != 0, GCK_DATA_FAILURE);
-	g_return_val_if_fail (cih != NULL, GCK_DATA_FAILURE);
-	g_return_val_if_fail (data != NULL && n_data != 0, GCK_DATA_FAILURE);
-	
-	init_quarks ();
-	
-	/* PKCS#5 PBE */
-	if (oid_scheme == OID_PBE_MD2_DES_CBC)
-		ret = gck_data_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
-		                                          GCRY_MD_MD2, password, n_password, data, n_data, cih);
-
-	else if (oid_scheme == OID_PBE_MD2_RC2_CBC)
-		/* RC2-64 has no implementation in libgcrypt */
-		ret = GCK_DATA_UNRECOGNIZED;
-	else if (oid_scheme == OID_PBE_MD5_DES_CBC)
-		ret = gck_data_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
-		                                          GCRY_MD_MD5, password, n_password, data, n_data, cih);
-	else if (oid_scheme == OID_PBE_MD5_RC2_CBC)
-		/* RC2-64 has no implementation in libgcrypt */
-		ret = GCK_DATA_UNRECOGNIZED;
-	else if (oid_scheme == OID_PBE_SHA1_DES_CBC)
-		ret = gck_data_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
-		                                          GCRY_MD_SHA1, password, n_password, data, n_data, cih);
-	else if (oid_scheme == OID_PBE_SHA1_RC2_CBC)
-		/* RC2-64 has no implementation in libgcrypt */
-		ret = GCK_DATA_UNRECOGNIZED;
-
-	
-	/* PKCS#5 PBES2 */
-	else if (oid_scheme == OID_PBES2)
-		ret = gck_data_der_read_cipher_pkcs5_pbes2 (password, n_password, data, n_data, cih);
-
-		
-	/* PKCS#12 PBE */
-	else if (oid_scheme == OID_PKCS12_PBE_ARCFOUR_SHA1)
-		ret = gck_data_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 
-		                                           password, n_password, data, n_data, cih);
-	else if (oid_scheme == OID_PKCS12_PBE_RC4_40_SHA1)
-		/* RC4-40 has no implementation in libgcrypt */;
-
-	else if (oid_scheme == OID_PKCS12_PBE_3DES_SHA1)
-		ret = gck_data_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 
-		                                           password, n_password, data, n_data, cih);
-	else if (oid_scheme == OID_PKCS12_PBE_2DES_SHA1) 
-		/* 2DES has no implementation in libgcrypt */;
-		
-	else if (oid_scheme == OID_PKCS12_PBE_RC2_128_SHA1)
-		ret = gck_data_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC, 
-		                                           password, n_password, data, n_data, cih);
-
-	else if (oid_scheme == OID_PKCS12_PBE_RC2_40_SHA1)
-		ret = gck_data_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC, 
-		                                           password, n_password, data, n_data, cih);
-
-	if (ret == GCK_DATA_UNRECOGNIZED)
-    		g_message ("unsupported or unrecognized cipher oid: %s", g_quark_to_string (oid_scheme));
-    	return ret;
-}
-
-GckDataResult
-gck_data_der_read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, int hash_algo, 
-                                    const gchar *password, gsize n_password, const guchar *data, 
-                                    gsize n_data, gcry_cipher_hd_t *cih)
-{
-	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	gcry_error_t gcry;
-	GckDataResult ret;
-	const guchar *salt;
-	gsize n_salt;
-	gsize n_block, n_key;
-	guint iterations;
-	guchar *key = NULL;
-	guchar *iv = NULL;
-
-	g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, GCK_DATA_FAILURE);
-	g_return_val_if_fail (cih != NULL, GCK_DATA_FAILURE);
-	g_return_val_if_fail (data != NULL && n_data != 0, GCK_DATA_FAILURE);
-
-	*cih = NULL;	
-	ret = GCK_DATA_UNRECOGNIZED;
-	
-	/* Check if we can use this algorithm */
-	if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0 ||
-	    gcry_md_test_algo (hash_algo) != 0)
-		goto done;
-	
-	asn = egg_asn1_decode ("PKIX1.pkcs-5-PBE-params", data, n_data);
-	if (!asn) 
-		goto done;
-		
-	ret = GCK_DATA_FAILURE;
-		
-	salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
-	if (!salt)
-		goto done;
-	if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
-		iterations = 1;
-		
-	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	g_return_val_if_fail (n_key > 0, GCK_DATA_FAILURE);
-	n_block = gcry_cipher_get_algo_blklen (cipher_algo);
-		
-	if (!gck_crypto_symkey_generate_pbe (cipher_algo, hash_algo, password, n_password, salt,
-	                                     n_salt, iterations, &key, n_block > 1 ? &iv : NULL))
-		goto done;
-		
-	gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
-	if (gcry != 0) {
-		g_warning ("couldn't create cipher: %s", gcry_strerror (gcry));
-		goto done;
-	}
-	
-	if (iv) 
-		gcry_cipher_setiv (*cih, iv, n_block);
-	gcry_cipher_setkey (*cih, key, n_key);
-	
-	ret = GCK_DATA_SUCCESS;
-
-done:
-	gcry_free (iv);
-	gcry_free (key);
-	
-	if (asn)
-		asn1_delete_structure (&asn);
-		
-	return ret;
-}
-
-static gboolean
-setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
-{
-	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	gcry_error_t gcry;
-	const guchar *iv;
-	gsize n_iv;
-	guint version;
-	
-	g_assert (data);
-
-	asn = egg_asn1_decode ("PKIX1.pkcs-5-rc2-CBC-params", data, n_data);
-	if (!asn) 
-		return GCK_DATA_UNRECOGNIZED;
-		
-	if (!egg_asn1_read_uint (asn, "rc2ParameterVersion", &version))
-		return GCK_DATA_FAILURE;
-	
-	iv = egg_asn1_read_content (asn, data, n_data, "iv", &n_iv);
-	asn1_delete_structure (&asn);
-
-	if (!iv)
-		return GCK_DATA_FAILURE;
-		
-	gcry = gcry_cipher_setiv (cih, iv, n_iv);
-			
-	if (gcry != 0) {
-		g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
-		return GCK_DATA_FAILURE;
-	}
-	
-	return GCK_DATA_SUCCESS;
-}
-
-static gboolean
-setup_pkcs5_des_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
-{
-	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	gcry_error_t gcry;
-	const guchar *iv;
-	gsize n_iv;
-	
-	g_assert (data);
-
-	asn = egg_asn1_decode ("PKIX1.pkcs-5-des-EDE3-CBC-params", data, n_data);
-	if (!asn)
-		asn = egg_asn1_decode ("PKIX1.pkcs-5-des-CBC-params", data, n_data);
-	if (!asn) 
-		return GCK_DATA_UNRECOGNIZED;
-	
-	iv = egg_asn1_read_content (asn, data, n_data, "", &n_iv);
-	asn1_delete_structure (&asn);
-
-	if (!iv)
-		return GCK_DATA_FAILURE;
-		
-	gcry = gcry_cipher_setiv (cih, iv, n_iv);
-			
-	if (gcry != 0) {
-		g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
-		return GCK_DATA_FAILURE;
-	}
-	
-	return GCK_DATA_SUCCESS;
-}
-
-static GckDataResult
-setup_pkcs5_pbkdf2_params (const gchar *password, gsize n_password, const guchar *data, 
-                           gsize n_data, int cipher_algo, gcry_cipher_hd_t cih)
-{
-	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GckDataResult ret;
-	gcry_error_t gcry;
-	guchar *key = NULL; 
-	const guchar *salt;
-	gsize n_salt, n_key;
-	guint iterations;
-	
-	g_assert (cipher_algo);
-	g_assert (data);
-	
-	ret = GCK_DATA_UNRECOGNIZED;
-
-	asn = egg_asn1_decode ("PKIX1.pkcs-5-PBKDF2-params", data, n_data);
-	if (!asn)
-		goto done;
-		
-	ret = GCK_DATA_FAILURE;
-		
-	if (!egg_asn1_read_uint (asn, "iterationCount", &iterations))
-		iterations = 1;
-	salt = egg_asn1_read_content (asn, data, n_data, "salt.specified", &n_salt);
-	if (!salt)
-		goto done;
-				
-	if (!gck_crypto_symkey_generate_pbkdf2 (cipher_algo, GCRY_MD_SHA1, password, n_password, 
-	                                        salt, n_salt, iterations, &key, NULL))
-		goto done;
-
-	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	g_return_val_if_fail (n_key > 0, GCK_DATA_FAILURE);
-	
-	gcry = gcry_cipher_setkey (cih, key, n_key);
-	if (gcry != 0) {
-		g_message ("couldn't set %lu byte key on cipher", (gulong)n_key);
-		goto done;
-	}
-	
-	ret = GCK_DATA_SUCCESS;
-	                                         
-done:
-	gcry_free (key);
-	if (asn)
-		asn1_delete_structure (&asn);
-	return ret;
-}
-
-GckDataResult
-gck_data_der_read_cipher_pkcs5_pbes2 (const gchar *password, gsize n_password, const guchar *data, 
-                                      gsize n_data, gcry_cipher_hd_t *cih)
-{
-	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GckDataResult r, ret;
-	GQuark key_deriv_algo, enc_oid;
-	gcry_error_t gcry;
-	int algo, mode;
-	int beg, end, res;
-
-	g_return_val_if_fail (cih != NULL, GCK_DATA_FAILURE);
-	g_return_val_if_fail (data != NULL && n_data != 0, GCK_DATA_FAILURE);
-	
-	init_quarks ();
-	
-	*cih = NULL;
-	ret = GCK_DATA_UNRECOGNIZED;
-	
-	asn = egg_asn1_decode ("PKIX1.pkcs-5-PBES2-params", data, n_data);
-	if (!asn)
-		goto done;
-		
-	res = GCK_DATA_FAILURE;
-	algo = mode = 0;
-	
-	/* Read in all the encryption type */
-	enc_oid = egg_asn1_read_oid (asn, "encryptionScheme.algorithm");
-	if (!enc_oid)
-		goto done;	
-	if (enc_oid == OID_DES_EDE3_CBC)
-		algo = GCRY_CIPHER_3DES;
-	else if (enc_oid == OID_DES_CBC)
-		algo = GCRY_CIPHER_DES;
-	else if (enc_oid == OID_DES_RC2_CBC)
-		algo = GCRY_CIPHER_RFC2268_128;
-	else if (enc_oid == OID_DES_RC5_CBC)
-		/* RC5 doesn't exist in libgcrypt */;
-	
-	/* Unsupported? */
-	if (algo == 0 || gcry_cipher_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0) {
-		ret = GCK_DATA_UNRECOGNIZED;
-		goto done;
-	}
-
-	/* Instantiate our cipher */
-	gcry = gcry_cipher_open (cih, algo, GCRY_CIPHER_MODE_CBC, 0);
-	if (gcry != 0) {
-		g_warning ("couldn't create cipher: %s", gcry_cipher_algo_name (algo));
-		goto done;
-	}
-		
-	/* Read out the parameters */
-	if (asn1_der_decoding_startEnd (asn, data, n_data, "encryptionScheme.parameters",
-	                                &beg, &end) != ASN1_SUCCESS)
-		goto done;
-		
-	switch (algo) {
-	case GCRY_CIPHER_3DES:
-	case GCRY_CIPHER_DES:
-		r = setup_pkcs5_des_params (data + beg, end - beg + 1, *cih);
-		break;
-	case GCRY_CIPHER_RFC2268_128:
-		r = setup_pkcs5_rc2_params (data + beg, end - beg + 1, *cih);
-		break;
-	default:
-		/* Should have been caught on the oid check above */
-		g_assert_not_reached ();
-		r = GCK_DATA_UNRECOGNIZED;
-		break;
-	};
-
-	if (r != GCK_DATA_SUCCESS) {
-		ret = r;
-		goto done;
-	}
-
-	/* Read out the key creation paramaters */
-	key_deriv_algo = egg_asn1_read_oid (asn, "keyDerivationFunc.algorithm");
-	if (!key_deriv_algo)
-		goto done;
-	if (key_deriv_algo != OID_PBKDF2) {
-		g_message ("unsupported key derivation algorithm: %s", g_quark_to_string (key_deriv_algo));
-		ret = GCK_DATA_UNRECOGNIZED;
-		goto done;
-	}
-
-	if (asn1_der_decoding_startEnd (asn, data, n_data, "keyDerivationFunc.parameters",
-	                                &beg, &end) != ASN1_SUCCESS)
-		goto done;
-	
-	ret = setup_pkcs5_pbkdf2_params (password, n_password, data + beg, end - beg + 1, algo, *cih);
-
-done:
-	if (ret != GCK_DATA_SUCCESS && *cih) {
-		gcry_cipher_close (*cih);
-		*cih = NULL;
-	}
-	
-	if (asn)
-		asn1_delete_structure (&asn);
-	
-	return ret;
-}
-
-GckDataResult
-gck_data_der_read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password, 
-                                     gsize n_password, const guchar *data, gsize n_data, 
-                                     gcry_cipher_hd_t *cih)
-{
-	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	gcry_error_t gcry;
-	GckDataResult ret;
-	const guchar *salt;
-	gsize n_salt;
-	gsize n_block, n_key;
-	guint iterations;
-	guchar *key = NULL;
-	guchar *iv = NULL;
-	
-	g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, GCK_DATA_FAILURE);
-	g_return_val_if_fail (cih != NULL, GCK_DATA_FAILURE);
-	g_return_val_if_fail (data != NULL && n_data != 0, GCK_DATA_FAILURE);
-	
-	*cih = NULL;
-	ret = GCK_DATA_UNRECOGNIZED;
-	
-	/* Check if we can use this algorithm */
-	if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
-		goto done;
-	
-	asn = egg_asn1_decode ("PKIX1.pkcs-12-PbeParams", data, n_data);
-	if (!asn)
-		goto done;
-
-	ret = GCK_DATA_FAILURE;
-
-	salt = egg_asn1_read_content (asn, data, n_data, "salt", &n_salt);
-	if (!salt)
-		goto done;
-	if (!egg_asn1_read_uint (asn, "iterations", &iterations))
-		goto done;
-	
-	n_block = gcry_cipher_get_algo_blklen (cipher_algo);
-	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	
-	/* Generate IV and key using salt read above */
-	if (!gck_crypto_symkey_generate_pkcs12 (cipher_algo, GCRY_MD_SHA1, password, 
-	                                        n_password, salt, n_salt, iterations, &key, 
-	                                        n_block > 1 ? &iv : NULL))
-		goto done;
-		
-	gcry = gcry_cipher_open (cih, cipher_algo, cipher_mode, 0);
-	if (gcry != 0) {
-		g_warning ("couldn't create encryption cipher: %s", gcry_strerror (gcry));
-		goto done;
-	}
-	
-	if (iv) 
-		gcry_cipher_setiv (*cih, iv, n_block);
-	gcry_cipher_setkey (*cih, key, n_key);
-	
-	ret = GCK_DATA_SUCCESS;
-	
-done:
-	if (ret != GCK_DATA_SUCCESS && *cih) {
-		gcry_cipher_close (*cih);
-		*cih = NULL;
-	}
-	
-	gcry_free (iv);
-	gcry_free (key);
-	
-	if (asn)
-		asn1_delete_structure (&asn);
-	
-	return ret;
-}

Modified: trunk/pkcs11/gck/gck-data-der.h
==============================================================================
--- trunk/pkcs11/gck/gck-data-der.h	(original)
+++ trunk/pkcs11/gck/gck-data-der.h	Sun Jan 18 22:24:09 2009
@@ -118,24 +118,4 @@
 
 guchar*            gck_data_der_write_certificate          (ASN1_TYPE asn1, gsize *n_data);
 
-/* -----------------------------------------------------------------------------
- * CIPHERS
- */
- 
-GckDataResult      gck_data_der_read_cipher                 (GQuark oid_scheme, const gchar *password,
-                                                             gsize n_password, const guchar *data, gsize n_data, 
-                                                             gcry_cipher_hd_t *cih);
-
-GckDataResult      gck_data_der_read_cipher_pkcs5_pbe       (int cipher_algo, int cipher_mode, 
-                                                             int hash_algo, const gchar *password, gsize n_password,
-                                                             const guchar *data, gsize n_data, 
-                                                             gcry_cipher_hd_t *cih);
-
-GckDataResult      gck_data_der_read_cipher_pkcs5_pbes2     (const gchar *password, gsize n_password, const guchar *data, 
-                                                             gsize n_data, gcry_cipher_hd_t *cih);
-
-GckDataResult      gck_data_der_read_cipher_pkcs12_pbe      (int cipher_algo, int cipher_mode, 
-                                                             const gchar *password, gsize n_password, const guchar *data, 
-                                                             gsize n_data, gcry_cipher_hd_t *cih);
-
 #endif /*GKRPKIXDER_H_*/

Modified: trunk/pkcs11/gck/gck-data-file.c
==============================================================================
--- trunk/pkcs11/gck/gck-data-file.c	(original)
+++ trunk/pkcs11/gck/gck-data-file.c	Sun Jan 18 22:24:09 2009
@@ -30,6 +30,7 @@
 
 #include "egg/egg-buffer.h"
 #include "egg/egg-secure-memory.h"
+#include "egg/egg-symkey.h"
 
 #include <glib/gstdio.h>
 
@@ -361,7 +362,7 @@
 	
 	password = gck_login_get_password (login, &n_password);
 	
-	if (!gck_crypto_symkey_generate_simple (calgo, halgo, password, n_password, 
+	if (!egg_symkey_generate_simple (calgo, halgo, password, n_password, 
 	                                        salt, n_salt, iterations, &key, &iv)) {
 		gcry_free (key);
 		g_free (iv);

Modified: trunk/pkcs11/gck/gck-util.c
==============================================================================
--- trunk/pkcs11/gck/gck-util.c	(original)
+++ trunk/pkcs11/gck/gck-util.c	Sun Jan 18 22:24:09 2009
@@ -29,8 +29,6 @@
 /* Only access using atomic operations */
 static gint next_handle = 0x00000010;
 
-static const char HEXC[] = "0123456789ABCDEF";
-
 gulong*
 gck_util_ulong_alloc (gulong value)
 {
@@ -89,79 +87,3 @@
 {
 	return (CK_ULONG)g_atomic_int_exchange_and_add (&next_handle, 1);
 }
-
-guchar*
-gck_util_hex_decode (const gchar *data, gssize n_data, gsize *n_decoded)
-{
-	guchar *result;
-	guchar *decoded;
-	gushort j;
-	gint state = 0;
-	const gchar* pos;
-    
-	g_return_val_if_fail (data || !n_data, NULL);
-	g_return_val_if_fail (n_decoded, NULL);
-	
-	if (n_data == -1)
-		n_data = strlen (data);
-
-	decoded = result = g_malloc0 ((n_data / 2) + 1);
-	*n_decoded = 0;
-
-	while (n_data > 0) {
-    		if (!g_ascii_isspace (*data)) {
-    			
-	        	/* Find the position */
-			pos = strchr (HEXC, g_ascii_toupper (*data));
-			if (pos == 0)
-				break;
-
-			j = pos - HEXC;
-			if(!state) {
-				*decoded = (j & 0xf) << 4;
-				state = 1;
-			} else {      
-				*decoded |= (j & 0xf);
-				(*n_decoded)++;
-				decoded++;
-				state = 0;
-			}
-    		}
-      
-      		++data;
-      		--n_data;
-	}
-
-	/* Parsing error */
-	if (state != 0) {
-		g_free (result);
-		result = NULL;
-	}
-
-	return result;
-}
-
-gchar* 
-gck_util_hex_encode (const guchar *data, gsize n_data)
-{
-	gchar *result, *encoded;
-	guchar j;
-	
-	g_return_val_if_fail (data || !n_data, NULL);
-	
-	encoded = result = g_malloc0 (n_data * 2 + 1);
-	
-	while(n_data > 0) {
-		j = *(data) >> 4 & 0xf;
-		*(encoded++) = HEXC[j];
-    
-		j = *(data++) & 0xf;
-		*(encoded++) = HEXC[j];
-    
-		n_data--;
-	}
-
-	/* Make sure still null terminated */
-	g_assert (encoded[n_data * 2] == 0);
-	return result;
-}

Modified: trunk/pkcs11/gck/gck-util.h
==============================================================================
--- trunk/pkcs11/gck/gck-util.h	(original)
+++ trunk/pkcs11/gck/gck-util.h	Sun Jan 18 22:24:09 2009
@@ -47,11 +47,4 @@
 
 CK_ULONG              gck_util_next_handle                        (void);
 
-guchar*               gck_util_hex_decode                         (const gchar *data, 
-                                                                   gssize n_data, 
-                                                                   gsize *n_decoded);
-
-gchar*                gck_util_hex_encode                         (const guchar *data, 
-                                                                   gsize n_data);
-
 #endif /* GCKUTIL_H_ */

Modified: trunk/pkcs11/gck/tests/Makefile.am
==============================================================================
--- trunk/pkcs11/gck/tests/Makefile.am	(original)
+++ trunk/pkcs11/gck/tests/Makefile.am	Sun Jan 18 22:24:09 2009
@@ -7,11 +7,9 @@
 	
 # Test files should be listed in order they need to run
 UNIT_AUTO = \
-	unit-test-util.c \
 	unit-test-crypto.c \
 	unit-test-data-asn1.c \
 	unit-test-data-der.c \
-	unit-test-data-openssl.c \
 	unit-test-transaction.c \
 	unit-test-store.c \
 	unit-test-memory-store.c \

Modified: trunk/pkcs11/gck/tests/unit-test-crypto.c
==============================================================================
--- trunk/pkcs11/gck/tests/unit-test-crypto.c	(original)
+++ trunk/pkcs11/gck/tests/unit-test-crypto.c	Sun Jan 18 22:24:09 2009
@@ -72,190 +72,6 @@
 	dsakey = NULL;
 }
 
-const static struct {
-	const gchar *password;
-	int cipher_algo;
-	int hash_algo;
-	int iterations;
-	const gchar *salt;
-	
-	const gchar *result_simple;
-	const gchar *result_pkcs12;
-	const gchar *result_pbkdf2;
-	const gchar *result_pbe;
-} all_generation_tests[] = {
-	
-	{ /* 24 byte output */
-		"booo", GCRY_CIPHER_3DES, GCRY_MD_MD5, 1, 
-		"\x70\x4C\xFF\xD6\x2F\xBA\x03\xE9", 
-		"\x84\x12\xBB\x34\x94\x8C\x40\xAD\x97\x57\x96\x74\x5B\x6A\xFB\xF8\xD6\x61\x33\x51\xEA\x8C\xCF\xD8", 
-		NULL,
-		NULL,
-		NULL
-        },
-
-	{ /* 5 byte output */
-		"booo", GCRY_CIPHER_RFC2268_40, GCRY_MD_SHA1, 2048, 
-		"\x8A\x58\xC2\xE8\x7C\x1D\x80\x11",
-		NULL,
-		"\xD6\xA6\xF0\x76\x66",
-		NULL,
-		NULL
-	},
-	
-	{ /* Null Password, 5 byte output */
-		NULL, GCRY_CIPHER_RFC2268_40, GCRY_MD_SHA1, 2000,
-		"\x04\xE0\x1C\x3E\xF8\xF2\xE9\xFD",
-		NULL,
-		"\x98\x7F\x20\x97\x1E",
-		NULL,
-		NULL
-	},
-        
-	{ /* 24 byte output */
-		"booo", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
-		"\xBD\xEE\x0B\xC6\xCF\x43\xAC\x25",
-		NULL,
-		"\x3F\x38\x1B\x0E\x87\xEB\x19\xBE\xD1\x39\xDC\x5B\xC2\xD2\xB3\x3C\x35\xA8\xB8\xF9\xEE\x66\x48\x94",
-		"\x20\x25\x90\xD8\xD6\x98\x3E\x71\x10\x17\x1F\x51\x49\x87\x27\xCA\x97\x27\xD1\xC9\x72\xF8\x11\xBB",
-		NULL
-	},
-
-	{ /* Empty password, 24 byte output */
-		"", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
-		"\xF7\xCF\xD9\xCF\x1F\xF3\xAD\xF6",
-		NULL,
-		NULL,
-		"\x53\xE3\x35\x9E\x5D\xC1\x85\x1A\x71\x3A\x67\x4E\x80\x56\x13\xD6\x4E\x3E\x89\x43\xB7\x1D\x5F\x7F",
-		NULL
-	},
-
-	{ /* Empty password, 24 byte output */
-		"", GCRY_CIPHER_3DES, GCRY_MD_SHA1, 2048,
-		"\xD9\xB3\x2E\xC7\xBA\x1A\x8E\x15",
-		NULL,
-		"\x39\x70\x75\x7C\xF5\xE2\x13\x0B\x5D\xC2\x9D\x96\x8B\x71\xC7\xFC\x5B\x97\x1F\x79\x9F\x06\xFC\xA2",
-		NULL,
-		NULL
-	},
-	
-	{ /* 8 byte output */
-		"booo", GCRY_CIPHER_DES, GCRY_MD_MD5, 2048,
-		"\x93\x4C\x3D\x29\xA2\x42\xB0\xF5",
-		NULL, 
-		NULL,
-		NULL,
-		"\x8C\x67\x19\x7F\xB9\x23\xE2\x8D"
-	}
-};
-
-#define N_GENERATION_TESTS (sizeof (all_generation_tests) / sizeof (all_generation_tests[0]))
-
-DEFINE_TEST(generate_key_simple)
-{
-	int i;
-	gboolean ret;
-	guchar *key;
-	
-	for (i = 0; i < N_GENERATION_TESTS; ++i) {
-		
-		if (!all_generation_tests[i].result_simple)
-			continue;
-		
-		ret = gck_crypto_symkey_generate_simple (all_generation_tests[i].cipher_algo, 
-                                                         all_generation_tests[i].hash_algo,
-                                                         all_generation_tests[i].password, -1,
-                                                         (guchar*)all_generation_tests[i].salt, 8,
-                                                         all_generation_tests[i].iterations,
-                                                         &key, NULL);
-		g_assert (ret && "key generation failed");
-
-		ret = (memcmp (key, all_generation_tests[i].result_simple, 
-		               gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
-
-		g_assert (ret && "invalid simple key generated"); 
-	}
-}
-
-DEFINE_TEST(generate_key_pkcs12)
-{
-	int i;
-	gboolean ret;
-	guchar *key;
-	
-	for (i = 0; i < N_GENERATION_TESTS; ++i) {
-		
-		if (!all_generation_tests[i].result_pkcs12)
-			continue;
-		
-		ret = gck_crypto_symkey_generate_pkcs12 (all_generation_tests[i].cipher_algo, 
-                                                         all_generation_tests[i].hash_algo,
-                                                         all_generation_tests[i].password, -1,
-                                                         (guchar*)all_generation_tests[i].salt, 8,
-                                                         all_generation_tests[i].iterations,
-                                                         &key, NULL);
-		g_assert ("failed to generate pkcs12 key" && ret);
-		
-		ret = (memcmp (key, all_generation_tests[i].result_pkcs12, 
-			        gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
-			
-		g_assert ("invalid pkcs12 key generated" && ret); 
-	}
-}
-
-DEFINE_TEST(generate_key_pbkdf2)
-{
-	int i;
-	gboolean ret;
-	guchar *key;
-	
-	for (i = 0; i < N_GENERATION_TESTS; ++i) {
-		
-		if (!all_generation_tests[i].result_pbkdf2)
-			continue;
-		
-		ret = gck_crypto_symkey_generate_pbkdf2 (all_generation_tests[i].cipher_algo, 
-                                                         all_generation_tests[i].hash_algo,
-                                                         all_generation_tests[i].password, -1,
-                                                         (guchar*)all_generation_tests[i].salt, 8,
-                                                         all_generation_tests[i].iterations,
-                                                         &key, NULL);
-		g_assert ("failed to generate pbkdf2 key" && ret);
-			
-		ret = (memcmp (key, all_generation_tests[i].result_pbkdf2, 
-			        gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
-		
-		g_assert ("invalid pbkdf2 key generated" && ret); 
-	}
-}
-
-DEFINE_TEST(generate_key_pbe)
-{
-	int i;
-	gboolean ret;
-	guchar *key;
-	
-	for (i = 0; i < N_GENERATION_TESTS; ++i) {
-		
-		if (!all_generation_tests[i].result_pbe)
-			continue;
-		
-		ret = gck_crypto_symkey_generate_pbe (all_generation_tests[i].cipher_algo, 
-                                                      all_generation_tests[i].hash_algo,
-                                                      all_generation_tests[i].password, -1,
-                                                      (guchar*)all_generation_tests[i].salt, 8,
-                                                      all_generation_tests[i].iterations,
-                                                      &key, NULL);
-		g_assert ("failed to generate pbe key" && ret);
-		
-		ret = (memcmp (key, all_generation_tests[i].result_pbe, 
-			        gcry_cipher_get_algo_keylen (all_generation_tests[i].cipher_algo)) == 0);
-			
-		g_assert ("invalid pbe key generated" && ret); 
-			
-	}
-}
-
 DEFINE_TEST(parse_key)
 {
 	gcry_sexp_t sexp = NULL;

Modified: trunk/pkcs11/roots-store/gck-roots-module.c
==============================================================================
--- trunk/pkcs11/roots-store/gck-roots-module.c	(original)
+++ trunk/pkcs11/roots-store/gck-roots-module.c	Sun Jan 18 22:24:09 2009
@@ -25,10 +25,11 @@
 #include "gck-roots-module.h"
 #include "gck-roots-certificate.h"
 
-#include "gck/gck-data-pem.h"
 #include "gck/gck-file-tracker.h"
 #include "gck/gck-serializable.h"
 
+#include "egg/egg-openssl.h"
+
 #include <string.h>
 
 struct _GckRootsModule {
@@ -204,7 +205,7 @@
 	g_list_free (objects);
 	
 	/* Try and parse the PEM */
-	num = gck_data_pem_parse (data, n_data, parsed_pem_block, &ctx);
+	num = egg_openssl_pem_parse (data, n_data, parsed_pem_block, &ctx);
 
 	/* If no PEM data, try to parse directly as DER  */
 	if (ctx.count == 0) {

Modified: trunk/pkcs11/ssh-store/gck-ssh-openssh.c
==============================================================================
--- trunk/pkcs11/ssh-store/gck-ssh-openssh.c	(original)
+++ trunk/pkcs11/ssh-store/gck-ssh-openssh.c	Sun Jan 18 22:24:09 2009
@@ -3,11 +3,10 @@
 
 #include "gck/gck-data-asn1.h"
 #include "gck/gck-data-der.h"
-#include "gck/gck-data-openssl.h"
-#include "gck/gck-data-pem.h"
 #include "gck/gck-data-types.h"
 
 #include "egg/egg-buffer.h"
+#include "egg/egg-openssl.h"
 
 typedef struct _ParsePrivate {
 	gcry_sexp_t sexp;
@@ -163,7 +162,7 @@
 	gint length;
 	
 	/* Decrypt, this will result in garble if invalid password */	
-	res = gck_data_openssl_decrypt_block (dekinfo, password, n_password, 
+	res = egg_openssl_decrypt_block (dekinfo, password, n_password, 
 	                                      data, n_data, &decrypted, &n_decrypted);
 	if (!res)
 		return FALSE;
@@ -214,7 +213,7 @@
 		return;
 	
 	/* If it's encrypted ... */
-	dekinfo = gck_data_openssl_get_dekinfo (headers);
+	dekinfo = egg_openssl_get_dekinfo (headers);
 	if (dekinfo) {
 		ctx->result = load_encrypted_key (data, n_data, dekinfo, ctx->password, 
 		                                  ctx->n_password, &ctx->sexp);
@@ -346,7 +345,7 @@
 	ctx.password = password;
 	ctx.n_password = n_password;
 	
-	num = gck_data_pem_parse (data, n_data, parsed_pem_block, &ctx);
+	num = egg_openssl_pem_parse (data, n_data, parsed_pem_block, &ctx);
 
 	/* Didn't find any private key there */
 	if (num == 0 || !ctx.seen) {

Modified: trunk/pkcs11/user-store/gck-user-storage.c
==============================================================================
--- trunk/pkcs11/user-store/gck-user-storage.c	(original)
+++ trunk/pkcs11/user-store/gck-user-storage.c	Sun Jan 18 22:24:09 2009
@@ -33,6 +33,8 @@
 #include "gck/gck-serializable.h"
 #include "gck/gck-util.h"
 
+#include "egg/egg-hex.h"
+
 #include <glib/gstdio.h>
 
 #include <libtasn1.h>
@@ -175,7 +177,7 @@
 	if (name == NULL) {
 		data = gck_object_get_attribute_data (object, CKA_ID, &n_data);
 		if (data && n_data)
-			name = gck_util_hex_encode (data, n_data);
+			name = egg_hex_encode (data, n_data);
 		g_free (data);
 	}
 	



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]