[gnome-keyring/dbus-api] [pkcs11] Refactor RSA and DSA mechanism support.



commit 94abeee297914b50fa3f2f27f8ef4ad9e0b106c3
Author: Stef Walter <stef memberwebs com>
Date:   Thu Nov 12 18:35:21 2009 +0000

    [pkcs11] Refactor RSA and DSA mechanism support.
    
    This is so we can support other non PK algorithms like
    DH and AES (for the wrapping of secret items, eg).

 pkcs11/gck/Makefile.am                             |    4 +-
 pkcs11/gck/gck-certificate.c                       |    4 +-
 pkcs11/gck/gck-crypto.c                            |  786 +++-----------------
 pkcs11/gck/gck-crypto.h                            |  177 ++---
 pkcs11/gck/gck-data-der.c                          |   50 +-
 pkcs11/gck/gck-key.h                               |   71 --
 pkcs11/gck/gck-mechanism-dsa.c                     |  144 ++++
 pkcs11/gck/gck-mechanism-dsa.h                     |   49 ++
 pkcs11/gck/gck-mechanism-rsa.c                     |  387 ++++++++++
 pkcs11/gck/gck-mechanism-rsa.h                     |   92 +++
 pkcs11/gck/gck-private-xsa-key.c                   |   20 +-
 pkcs11/gck/gck-private-xsa-key.h                   |    6 +-
 pkcs11/gck/gck-public-xsa-key.c                    |   32 +-
 pkcs11/gck/gck-public-xsa-key.h                    |    6 +-
 pkcs11/gck/gck-session.c                           |   60 +-
 pkcs11/gck/gck-session.h                           |    6 +
 pkcs11/gck/{gck-key.c => gck-sexp-key.c}           |  191 ++---
 pkcs11/gck/gck-sexp-key.h                          |   71 ++
 pkcs11/gck/gck-sexp.c                              |  203 +++++
 pkcs11/gck/gck-sexp.h                              |   20 +-
 pkcs11/gck/gck-types.h                             |    2 +-
 pkcs11/gck/tests/Makefile.am                       |    2 +-
 pkcs11/gck/tests/unit-test-data-der.c              |    3 +-
 .../tests/{unit-test-crypto.c => unit-test-sexp.c} |   29 +-
 pkcs11/ssh-store/gck-ssh-private-key.c             |    4 +-
 pkcs11/ssh-store/tests/p11-tests.conf              |    6 +-
 pkcs11/ssh-store/tests/unit-test-ssh-openssh.c     |   10 +-
 pkcs11/user-store/gck-user-private-key.c           |   12 +-
 pkcs11/user-store/gck-user-public-key.c            |    4 +-
 29 files changed, 1373 insertions(+), 1078 deletions(-)
---
diff --git a/pkcs11/gck/Makefile.am b/pkcs11/gck/Makefile.am
index 3427ada..0833682 100644
--- a/pkcs11/gck/Makefile.am
+++ b/pkcs11/gck/Makefile.am
@@ -29,8 +29,9 @@ libgck_la_SOURCES = \
 	gck-data-types.h \
 	gck-factory.c gck-factory.h \
 	gck-file-tracker.c gck-file-tracker.h \
-	gck-key.c gck-key.h \
 	gck-manager.c gck-manager.h \
+	gck-mechanism-dsa.c gck-mechanism-dsa.h \
+	gck-mechanism-rsa.c gck-mechanism-rsa.h \
 	gck-memory-store.c gck-memory-store.h \
 	gck-module.c gck-module.h gck-module-ep.h \
 	gck-object.c gck-object.h \
@@ -40,6 +41,7 @@ libgck_la_SOURCES = \
 	gck-serializable.c gck-serializable.h \
 	gck-session.c gck-session.h \
 	gck-sexp.c gck-sexp.h \
+	gck-sexp-key.c gck-sexp-key.h \
 	gck-store.c gck-store.h \
 	gck-timer.c gck-timer.h \
 	gck-transaction.c gck-transaction.h \
diff --git a/pkcs11/gck/gck-certificate.c b/pkcs11/gck/gck-certificate.c
index 9292651..a635daf 100644
--- a/pkcs11/gck/gck-certificate.c
+++ b/pkcs11/gck/gck-certificate.c
@@ -28,7 +28,7 @@
 #include "gck-data-asn1.h"
 #include "gck-data-der.h"
 #include "gck-factory.h"
-#include "gck-key.h"
+#include "gck-sexp-key.h"
 #include "gck-manager.h"
 #include "gck-session.h"
 #include "gck-sexp.h"
@@ -562,7 +562,7 @@ gck_certificate_real_load (GckSerializable *base, GckSecret *login, const guchar
 			self->pv->key = gck_certificate_key_new (gck_object_get_module (GCK_OBJECT (self)),
 			                                         gck_object_get_manager (GCK_OBJECT (self)),
 			                                         self);
-		gck_key_set_base_sexp (GCK_KEY (self->pv->key), wrapper);
+		gck_sexp_key_set_base (GCK_SEXP_KEY (self->pv->key), wrapper);
 		gck_sexp_unref (wrapper);
 		break;
 
diff --git a/pkcs11/gck/gck-crypto.c b/pkcs11/gck/gck-crypto.c
index 294b0f1..d2a1429 100644
--- a/pkcs11/gck/gck-crypto.c
+++ b/pkcs11/gck/gck-crypto.c
@@ -22,41 +22,22 @@
 #include "config.h"
 
 #include "gck-crypto.h"
+#include "gck-mechanism-dsa.h"
+#include "gck-mechanism-rsa.h"
+#include "gck-session.h"
+#include "gck-sexp.h"
+#include "gck-sexp-key.h"
 
 #include "egg/egg-libgcrypt.h"
 #include "egg/egg-secure-memory.h"
 
 /* ----------------------------------------------------------------------------
- * INTERNAL
+ * PUBLIC
  */
 
-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)
+CK_RV
+gck_crypto_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;
@@ -89,17 +70,11 @@ data_to_sexp (const gchar *format, guint nbits, GckCryptoPadding padding,
 
 	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, ...)
+CK_RV
+gck_crypto_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;
@@ -115,7 +90,7 @@ sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
 
 	/* First try and dig out sexp child based on arguments */
 	va_start (va, padding);
-	at = sexp_get_childv (sexp, va);
+	at = gck_sexp_get_childv (sexp, va);
 	va_end (va);
 	
 	/* It's expected we would find it */
@@ -159,81 +134,27 @@ sexp_to_data (gcry_sexp_t sexp, guint bits, CK_BYTE_PTR data,
 	return CKR_OK;
 }
 
-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;
-	}
+CK_RV
+gck_crypto_encrypt (GckSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+                    CK_ULONG n_data, CK_BYTE_PTR encrypted, CK_ULONG_PTR n_encrypted)
+{
+	GckSexp *sexp;
 
-	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);
+	switch (mech) {
+	case CKM_RSA_PKCS:
+	case CKM_RSA_X_509:
+		sexp = gck_session_get_crypto_state (session);
+		g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+		return gck_crypto_encrypt_xsa (gck_sexp_get (sexp), mech, data, n_data, encrypted, n_encrypted);
+	default:
+		g_return_val_if_reached (CKR_GENERAL_ERROR);
 	}
 }
 
-static guchar*
-unpad_rsa_pkcs1 (guchar bt, guint n_modulus, const guchar* padded,
-                 gsize n_padded, gsize *n_raw)
-{ 
-	const guchar *at;
-	guint check;
-	guchar *raw;
-	
-	check = (n_modulus + 7) / 8;
-	
-	/* The absolute minimum size including padding */
-	g_return_val_if_fail (check >= 3 + 8, NULL);
-	
-	if (n_padded != check)
-		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)
+gck_crypto_encrypt_xsa (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;
@@ -242,7 +163,7 @@ gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 	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))
+	if (!gck_sexp_parse_key (sexp, &algorithm, NULL, NULL))
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
 
 	/* 
@@ -254,11 +175,11 @@ gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 	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);
+		rv = gck_mechanism_rsa_encrypt (sexp, gck_mechanism_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);
+		rv = gck_mechanism_rsa_encrypt (sexp, gck_mechanism_rsa_pad_raw, data, n_data, encrypted, n_encrypted);
 		break;
 	default:
 		/* Again shouldn't be reached */
@@ -269,53 +190,25 @@ gck_crypto_encrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 }
 
 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)
+gck_crypto_decrypt (GckSession *session, CK_MECHANISM_TYPE mech, 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_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;
-	}
+	GckSexp *sexp;
 
-	/* 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;
+	switch (mech) {
+	case CKM_RSA_PKCS:
+	case CKM_RSA_X_509:
+		sexp = gck_session_get_crypto_state (session);
+		g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+		return gck_crypto_decrypt_xsa (gck_sexp_get (sexp), mech, encrypted, n_encrypted, data, n_data);
+	default:
+		g_return_val_if_reached (CKR_GENERAL_ERROR);
 	}
-
-	/* 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)
+gck_crypto_decrypt_xsa (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;
@@ -324,7 +217,7 @@ gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encryp
 	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))
+	if (!gck_sexp_parse_key (sexp, &algorithm, NULL, NULL))
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
 
 	/* 
@@ -336,11 +229,11 @@ gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encryp
 	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);
+		rv = gck_mechanism_rsa_decrypt (sexp, gck_mechanism_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);
+		rv = gck_mechanism_rsa_decrypt (sexp, NULL, encrypted, n_encrypted, data, n_data);
 		break;
 	default:
 		/* Again shouldn't be reached */
@@ -351,56 +244,26 @@ gck_crypto_decrypt (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR encryp
 }
 
 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)
+gck_crypto_sign (GckSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+                 CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG_PTR n_signature)
 {
-	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);
+	GckSexp *sexp;
 
-	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;
+	switch (mech) {
+	case CKM_RSA_PKCS:
+	case CKM_RSA_X_509:
+	case CKM_DSA:
+		sexp = gck_session_get_crypto_state (session);
+		g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+		return gck_crypto_sign_xsa (gck_sexp_get (sexp), mech, data, n_data, signature, n_signature);
+	default:
+		g_return_val_if_reached (CKR_GENERAL_ERROR);
 	}
-
-	/* 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)
+gck_crypto_sign_xsa (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;
@@ -409,7 +272,7 @@ gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 	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))
+	if (!gck_sexp_parse_key (sexp, &algorithm, NULL, NULL))
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
 
 	/* 
@@ -421,15 +284,15 @@ gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 	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);
+		rv = gck_mechanism_rsa_sign (sexp, gck_mechanism_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);
+		rv = gck_mechanism_rsa_sign (sexp, gck_mechanism_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);
+		rv = gck_mechanism_dsa_sign (sexp, data, n_data, signature, n_signature);
 		break;
 	default:
 		/* Again shouldn't be reached */
@@ -440,113 +303,26 @@ gck_crypto_sign (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 }
 
 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)
+gck_crypto_verify (GckSession *session, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
+                   CK_ULONG n_data, CK_BYTE_PTR signature, CK_ULONG 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;
-	}
+	GckSexp *sexp;
 
-	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;
-		}
+	switch (mech) {
+	case CKM_RSA_PKCS:
+	case CKM_RSA_X_509:
+	case CKM_DSA:
+		sexp = gck_session_get_crypto_state (session);
+		g_return_val_if_fail (sexp, CKR_GENERAL_ERROR);
+		return gck_crypto_verify_xsa (gck_sexp_get (sexp), mech, data, n_data, signature, n_signature);
+	default:
+		g_return_val_if_reached (CKR_GENERAL_ERROR);
 	}
-	
-	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)
+gck_crypto_verify_xsa (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;
@@ -555,7 +331,7 @@ gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 	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))
+	if (!gck_sexp_parse_key (sexp, &algorithm, NULL, NULL))
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
 
 	/* 
@@ -567,15 +343,15 @@ gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 	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);
+		rv = gck_mechanism_rsa_verify (sexp, gck_mechanism_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);
+		rv = gck_mechanism_rsa_verify (sexp, gck_mechanism_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);
+		rv = gck_mechanism_dsa_verify (sexp, data, n_data, signature, n_signature);
 		break;
 	default:
 		/* Again shouldn't be reached */
@@ -585,400 +361,62 @@ gck_crypto_verify (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_BYTE_PTR data,
 	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)
-{
-	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;
-}
-
 CK_RV 
-gck_crypto_perform (gcry_sexp_t sexp, CK_MECHANISM_TYPE mech, CK_ATTRIBUTE_TYPE method, 
+gck_crypto_perform (GckSession *session, 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 (GCK_IS_SESSION (session), 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);
+		return gck_crypto_encrypt (session, mech, bufone, n_bufone, buftwo, n_buftwo);
 	case CKA_DECRYPT:
-		return gck_crypto_decrypt (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
+		return gck_crypto_decrypt (session, mech, bufone, n_bufone, buftwo, n_buftwo);
 	case CKA_SIGN:
-		return gck_crypto_sign (sexp, mech, bufone, n_bufone, buftwo, n_buftwo);
+		return gck_crypto_sign (session, mech, bufone, n_bufone, buftwo, n_buftwo);
 	case CKA_VERIFY:
-		return gck_crypto_verify (sexp, mech, bufone, n_bufone, buftwo, *n_buftwo);
+		return gck_crypto_verify (session, mech, bufone, n_bufone, buftwo, *n_buftwo);
 	default:
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
 	}
 }
 
 /* ----------------------------------------------------------------------------
- * SEXP FUNCTIONS
+ * PREPARE FUNCTIONS
  */
 
-#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;
-		
-	data = gcry_sexp_nth_data (child, 0, &n_data);
-	if (!data)
-		goto done;
-		
-	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)
+CK_RV
+gck_crypto_prepare (GckSession *session, CK_MECHANISM_TYPE mech, GckObject *key)
 {
-	gcry_sexp_t numbers;
-	int algorithm;
+	g_return_val_if_fail (GCK_IS_SESSION (session), CKR_GENERAL_ERROR);
 
-	if (!gck_crypto_sexp_parse_key (privkey, &algorithm, NULL, &numbers))
-		g_return_val_if_reached (FALSE);
-		
-	switch (algorithm) {
-	case GCRY_PK_RSA:
-		*pubkey = rsa_numbers_to_public (numbers);
-		break;
-	case GCRY_PK_DSA:
-		*pubkey = dsa_numbers_to_public (numbers);
-		break;
+	switch (mech) {
+	case CKM_RSA_PKCS:
+	case CKM_RSA_X_509:
+	case CKM_DSA:
+		return gck_crypto_prepare_xsa (session, mech, key);
 	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 + 7) / 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;
+		g_return_val_if_reached (CKR_GENERAL_ERROR);
+	}
 }
 
-guchar*
-gck_crypto_rsa_pad_one (guint n_modulus, const guchar* raw, 
-                        gsize n_raw, gsize *n_padded)
+CK_RV
+gck_crypto_prepare_xsa (GckSession *session, CK_MECHANISM_TYPE mech, GckObject *key)
 {
-	gint total, n_pad;
-	guchar *padded;
-
-	/*
-	 * 0x00 0x01 0xFF 0xFF ... 0x00 0x?? 0x?? 0x?? ...
-         *      type  padding              data
-         */
-
-	total = (n_modulus + 7) / 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;
-}
+	GckSexp *sexp;
 
-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 + 7) / 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;
-}
+	g_return_val_if_fail (GCK_IS_SESSION (session), CKR_GENERAL_ERROR);
+	g_return_val_if_fail (GCK_IS_SEXP_KEY (key), CKR_GENERAL_ERROR);
 
-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);
-}
+	/* Load up the actual sexp we're going to use */
+	sexp = gck_sexp_key_acquire_crypto_sexp (GCK_SEXP_KEY (key), session);
+	if (sexp == NULL)
+		return CKR_USER_NOT_LOGGED_IN;
 
-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);
+	gck_session_set_crypto_state (session, sexp, gck_sexp_unref);
+	return CKR_OK;
 }
 
 /* --------------------------------------------------------------------------
diff --git a/pkcs11/gck/gck-crypto.h b/pkcs11/gck/gck-crypto.h
index 623b544..1b2598a 100644
--- a/pkcs11/gck/gck-crypto.h
+++ b/pkcs11/gck/gck-crypto.h
@@ -22,141 +22,104 @@
 #ifndef GCKCRYPTO_H_
 #define GCKCRYPTO_H_
 
+#include "gck-types.h"
+
+#include "pkcs11/pkcs11.h"
+
 #include <glib.h>
 
 #include <gcrypt.h>
 
-#include "pkcs11/pkcs11.h"
-
 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_RV                    gck_crypto_prepare                            (GckSession *session,
+                                                                        CK_MECHANISM_TYPE mech,
+                                                                        GckObject *key);
+
+CK_RV                    gck_crypto_prepare_xsa                        (GckSession *session,
+                                                                        CK_MECHANISM_TYPE mech,
+                                                                        GckObject *key);
+
+CK_RV                    gck_crypto_perform                            (GckSession *session,
+                                                                        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_RV                    gck_crypto_encrypt                            (GckSession *session,
+                                                                        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_RV                    gck_crypto_encrypt_xsa                        (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_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_RV                    gck_crypto_decrypt                            (GckSession *session,
+                                                                        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_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_decrypt_xsa                        (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_sign_rsa                           (gcry_sexp_t sexp, 
-                                                                        GckCryptoPadding padding, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
+CK_RV                    gck_crypto_sign                               (GckSession *session,
+                                                                        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_dsa                           (gcry_sexp_t sexp, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
+CK_RV                    gck_crypto_sign_xsa                           (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_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_RV                    gck_crypto_verify                             (GckSession *session,
+                                                                        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_dsa                         (gcry_sexp_t sexp, 
-                                                                        CK_BYTE_PTR data, 
-                                                                        CK_ULONG n_data, 
-                                                                        CK_BYTE_PTR signature, 
+CK_RV                    gck_crypto_verify_xsa                         (gcry_sexp_t sexp,
+                                                                        CK_MECHANISM_TYPE mech,
+                                                                        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, 
+CK_RV                    gck_crypto_sexp_to_data                       (gcry_sexp_t sexp,
+                                                                        guint bits,
+                                                                        CK_BYTE_PTR data,
+                                                                        CK_ULONG *n_data,
+                                                                        GckCryptoPadding padding,
                                                                         ...) 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);
+CK_RV                    gck_crypto_data_to_sexp                       (const gchar *format,
+                                                                        guint nbits,
+                                                                        GckCryptoPadding padding,
+                                                                        CK_BYTE_PTR data,
+                                                                        CK_ULONG n_data,
+                                                                        gcry_sexp_t *sexp);
 
 #endif /* GCKCRYPTO_H_ */
diff --git a/pkcs11/gck/gck-data-der.c b/pkcs11/gck/gck-data-der.c
index b1e4e6c..37d8003 100644
--- a/pkcs11/gck/gck-data-der.c
+++ b/pkcs11/gck/gck-data-der.c
@@ -23,10 +23,10 @@
 
 #include "config.h"
 
-#include "gck-crypto.h"
 #include "gck-data-asn1.h"
 #include "gck-data-der.h"
 #include "gck-data-types.h"
+#include "gck-sexp.h"
 
 #include "egg/egg-secure-memory.h"
 #include "egg/egg-symkey.h"
@@ -674,8 +674,8 @@ gck_data_der_write_public_key_rsa (gcry_sexp_t s_key, gsize *len)
 	                           "PK.RSAPublicKey", &asn);
 	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
 
-	if (!gck_crypto_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) || 
-	    !gck_crypto_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL))
+	if (!gck_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL))
 	    	goto done;
 	
 	if (!gck_data_asn1_write_mpi (asn, "modulus", n) ||
@@ -707,12 +707,12 @@ gck_data_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
 	                           "PK.RSAPrivateKey", &asn);
 	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
 
-	if (!gck_crypto_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) || 
-	    !gck_crypto_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &d, "rsa", "d", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &p, "rsa", "p", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &q, "rsa", "q", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL))
+	if (!gck_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &d, "rsa", "d", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &p, "rsa", "p", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &q, "rsa", "q", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL))
 		goto done;
 	
 	if (!gck_data_asn1_write_mpi (asn, "modulus", n) ||
@@ -778,10 +778,10 @@ gck_data_der_write_public_key_dsa (gcry_sexp_t s_key, gsize *len)
 	                           "PK.DSAPublicKey", &asn);
 	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
 
-	if (!gck_crypto_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) || 
-	    !gck_crypto_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL))
+	if (!gck_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL))
 	    	goto done;
 	
 	if (!gck_data_asn1_write_mpi (asn, "p", p) ||
@@ -820,7 +820,7 @@ gck_data_der_write_private_key_dsa_part (gcry_sexp_t skey, gsize *n_key)
 	                           "PK.DSAPrivatePart", &asn);
 	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
 
-	if (!gck_crypto_sexp_extract_mpi (skey, &x, "dsa", "x", NULL))
+	if (!gck_sexp_extract_mpi (skey, &x, "dsa", "x", NULL))
 	    	goto done;
 	
 	if (!gck_data_asn1_write_mpi (asn, "", x))
@@ -850,9 +850,9 @@ gck_data_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params)
 	                           "PK.DSAParameters", &asn);
 	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
 
-	if (!gck_crypto_sexp_extract_mpi (skey, &p, "dsa", "p", NULL) || 
-	    !gck_crypto_sexp_extract_mpi (skey, &q, "dsa", "q", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (skey, &g, "dsa", "g", NULL))
+	if (!gck_sexp_extract_mpi (skey, &p, "dsa", "p", NULL) ||
+	    !gck_sexp_extract_mpi (skey, &q, "dsa", "q", NULL) ||
+	    !gck_sexp_extract_mpi (skey, &g, "dsa", "g", NULL))
 	    	goto done;
 	
 	if (!gck_data_asn1_write_mpi (asn, "p", p) ||
@@ -886,11 +886,11 @@ gck_data_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len)
 	                           "PK.DSAPrivateKey", &asn);
 	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
 
-	if (!gck_crypto_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) || 
-	    !gck_crypto_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL) ||
-	    !gck_crypto_sexp_extract_mpi (s_key, &x, "dsa", "x", NULL))
+	if (!gck_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL) ||
+	    !gck_sexp_extract_mpi (s_key, &x, "dsa", "x", NULL))
 	    	goto done;
 	
 	if (!gck_data_asn1_write_mpi (asn, "p", p) ||
@@ -925,7 +925,7 @@ gck_data_der_write_public_key (gcry_sexp_t s_key, gsize *len)
 	
 	g_return_val_if_fail (s_key != NULL, NULL);
 	
-	if (!gck_crypto_sexp_parse_key (s_key, &algorithm, &is_priv, NULL))
+	if (!gck_sexp_parse_key (s_key, &algorithm, &is_priv, NULL))
 		g_return_val_if_reached (NULL);
 	
 	g_return_val_if_fail (!is_priv, NULL);
@@ -948,7 +948,7 @@ gck_data_der_write_private_key (gcry_sexp_t s_key, gsize *len)
 	
 	g_return_val_if_fail (s_key != NULL, NULL);
 	
-	if (!gck_crypto_sexp_parse_key (s_key, &algorithm, &is_priv, NULL))
+	if (!gck_sexp_parse_key (s_key, &algorithm, &is_priv, NULL))
 		g_return_val_if_reached (NULL);
 	
 	g_return_val_if_fail (is_priv, NULL);
@@ -1043,7 +1043,7 @@ gck_data_der_write_private_pkcs8_plain (gcry_sexp_t skey, gsize *n_data)
 	init_quarks ();
 
 	/* Parse and check that the key is for real */
-	if (!gck_crypto_sexp_parse_key (skey, &algorithm, &is_priv, NULL))
+	if (!gck_sexp_parse_key (skey, &algorithm, &is_priv, NULL))
 		g_return_val_if_reached (NULL);
 	g_return_val_if_fail (is_priv == TRUE, NULL);
 	
diff --git a/pkcs11/gck/gck-mechanism-dsa.c b/pkcs11/gck/gck-mechanism-dsa.c
new file mode 100644
index 0000000..8b75a67
--- /dev/null
+++ b/pkcs11/gck/gck-mechanism-dsa.c
@@ -0,0 +1,144 @@
+/*
+ * 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  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  License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * 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 "gck-crypto.h"
+#include "gck-mechanism-dsa.h"
+#include "gck-session.h"
+#include "gck-sexp.h"
+#include "gck-sexp-key.h"
+
+#include "egg/egg-libgcrypt.h"
+#include "egg/egg-secure-memory.h"
+
+/* ----------------------------------------------------------------------------
+ * PUBLIC
+ */
+
+CK_RV
+gck_mechanism_dsa_sign (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 = gck_crypto_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 = gck_crypto_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_mechanism_dsa_verify (gcry_sexp_t sexp, CK_BYTE_PTR data, CK_ULONG n_data,
+                          CK_BYTE_PTR signature, CK_ULONG n_signature)
+{
+	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;
+}
diff --git a/pkcs11/gck/gck-mechanism-dsa.h b/pkcs11/gck/gck-mechanism-dsa.h
new file mode 100644
index 0000000..2434a5c
--- /dev/null
+++ b/pkcs11/gck/gck-mechanism-dsa.h
@@ -0,0 +1,49 @@
+/*
+ * 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  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  License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * 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 GCK_MECHANISM_DSA_H_
+#define GCK_MECHANISM_DSA_H_
+
+#include "gck-types.h"
+
+#include "pkcs11/pkcs11.h"
+
+#include <glib.h>
+
+#include <gcrypt.h>
+
+static const CK_MECHANISM_TYPE GCK_CRYPTO_DSA_MECHANISMS[] = {
+	CKM_DSA
+};
+
+CK_RV                    gck_mechanism_dsa_sign                        (gcry_sexp_t sexp,
+                                                                        CK_BYTE_PTR data,
+                                                                        CK_ULONG n_data,
+                                                                        CK_BYTE_PTR signature,
+                                                                        CK_ULONG_PTR n_signature);
+
+CK_RV                    gck_mechanism_dsa_verify                      (gcry_sexp_t sexp,
+                                                                        CK_BYTE_PTR data,
+                                                                        CK_ULONG n_data,
+                                                                        CK_BYTE_PTR signature,
+                                                                        CK_ULONG n_signature);
+
+#endif /* GCK_MECHANISM_DSA_H_ */
diff --git a/pkcs11/gck/gck-mechanism-rsa.c b/pkcs11/gck/gck-mechanism-rsa.c
new file mode 100644
index 0000000..fea02f7
--- /dev/null
+++ b/pkcs11/gck/gck-mechanism-rsa.c
@@ -0,0 +1,387 @@
+/*
+ * 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  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  License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * 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 "gck-mechanism-rsa.h"
+#include "gck-sexp.h"
+
+#include "egg/egg-libgcrypt.h"
+#include "egg/egg-secure-memory.h"
+
+/* ----------------------------------------------------------------------------
+ * INTERNAL
+ */
+
+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;
+	guint check;
+	guchar *raw;
+
+	check = (n_modulus + 7) / 8;
+
+	/* The absolute minimum size including padding */
+	g_return_val_if_fail (check >= 3 + 8, NULL);
+
+	if (n_padded != check)
+		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_mechanism_rsa_encrypt (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 = gck_crypto_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 = gck_crypto_sexp_to_data (sdata, nbits, encrypted, n_encrypted, NULL,
+	                              "enc-val", "rsa", "a", NULL);
+	gcry_sexp_release (sdata);
+
+	return rv;
+}
+
+CK_RV
+gck_mechanism_rsa_decrypt (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 = gck_crypto_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 = gck_crypto_sexp_to_data (splain, nbits, data, n_data, padding, "value", NULL);
+	gcry_sexp_release (splain);
+
+	return rv;
+}
+
+CK_RV
+gck_mechanism_rsa_sign (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 = gck_crypto_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 = gck_crypto_sexp_to_data (ssig, nbits, signature, n_signature, NULL, "rsa", "s", NULL);
+	gcry_sexp_release (ssig);
+
+	return rv;
+}
+
+CK_RV
+gck_mechanism_rsa_verify (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 = gck_crypto_data_to_sexp ("(data (flags raw) (value %m))",
+	                   nbits, padding, data, n_data, &sdata);
+	if (rv != CKR_OK)
+		return rv;
+
+	rv = gck_crypto_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;
+}
+
+/* ----------------------------------------------------------------------------
+ * PADDING FUNCTIONS
+ */
+
+
+guchar*
+gck_mechanism_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 + 7) / 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_mechanism_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 + 7) / 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_mechanism_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 + 7) / 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_mechanism_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_mechanism_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);
+}
diff --git a/pkcs11/gck/gck-mechanism-rsa.h b/pkcs11/gck/gck-mechanism-rsa.h
new file mode 100644
index 0000000..b263a57
--- /dev/null
+++ b/pkcs11/gck/gck-mechanism-rsa.h
@@ -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  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  License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * 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 GCK_MECHANISM_RSA_H_
+#define GCK_MECHANISM_RSA_H_
+
+#include "gck-crypto.h"
+#include "gck-types.h"
+
+#include "pkcs11/pkcs11.h"
+
+#include <glib.h>
+
+#include <gcrypt.h>
+
+static const CK_MECHANISM_TYPE GCK_CRYPTO_RSA_MECHANISMS[] = {
+	CKM_RSA_PKCS,
+	CKM_RSA_X_509
+};
+
+CK_RV                    gck_mechanism_rsa_encrypt                     (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_mechanism_rsa_decrypt                     (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_mechanism_rsa_sign                        (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_mechanism_rsa_verify                      (gcry_sexp_t sexp,
+                                                                        GckCryptoPadding padding,
+                                                                        CK_BYTE_PTR data,
+                                                                        CK_ULONG n_data,
+                                                                        CK_BYTE_PTR signature,
+                                                                        CK_ULONG n_signature);
+
+guchar*                  gck_mechanism_rsa_pad_raw                     (guint bits,
+                                                                        const guchar* raw,
+                                                                        gsize n_raw,
+                                                                        gsize *n_padded);
+
+guchar*                  gck_mechanism_rsa_pad_one                     (guint bits,
+                                                                        const guchar* raw,
+                                                                        gsize n_raw,
+                                                                        gsize *n_padded);
+
+guchar*                  gck_mechanism_rsa_pad_two                     (guint bits,
+                                                                        const guchar* raw,
+                                                                        gsize n_raw,
+                                                                        gsize *n_padded);
+
+guchar*                  gck_mechanism_rsa_unpad_one                   (guint bits,
+                                                                        const guchar *padded,
+                                                                        gsize n_padded,
+                                                                        gsize *n_raw);
+
+guchar*                  gck_mechanism_rsa_unpad_two                   (guint bits,
+                                                                        const guchar* padded,
+                                                                        gsize n_padded,
+                                                                        gsize *n_raw);
+
+#endif /* GCK_MECHANISM_RSA_H_ */
diff --git a/pkcs11/gck/gck-private-xsa-key.c b/pkcs11/gck/gck-private-xsa-key.c
index fa310ad..7b86b85 100644
--- a/pkcs11/gck/gck-private-xsa-key.c
+++ b/pkcs11/gck/gck-private-xsa-key.c
@@ -35,7 +35,7 @@ struct _GckPrivateXsaKeyPrivate {
 	GckSexp *sexp;
 };
 
-G_DEFINE_TYPE (GckPrivateXsaKey, gck_private_xsa_key, GCK_TYPE_KEY);
+G_DEFINE_TYPE (GckPrivateXsaKey, gck_private_xsa_key, GCK_TYPE_SEXP_KEY);
 
 /* -----------------------------------------------------------------------------
  * INTERNAL
@@ -201,6 +201,7 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
 {
 	GckPrivateXsaKey *self = GCK_PRIVATE_XSA_KEY (base);
 	gboolean have;
+	gint algorithm;
 
 	switch (attr->type) {
 	case CKA_CLASS:
@@ -213,7 +214,8 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
 		return gck_attribute_set_bool (attr, TRUE);
 
 	case CKA_DECRYPT:
-		return gck_attribute_set_bool (attr, gck_key_get_algorithm (GCK_KEY (self)) == GCRY_PK_RSA);
+		algorithm = gck_sexp_key_get_algorithm (GCK_SEXP_KEY (self));
+		return gck_attribute_set_bool (attr, algorithm == GCRY_PK_RSA);
 
 	case CKA_SIGN:
 		return gck_attribute_set_bool (attr, TRUE);
@@ -246,10 +248,10 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
 		return gck_attribute_set_bool (attr, !have);
 
 	case CKA_MODULUS:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "n", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_RSA, "n", attr);
 
 	case CKA_PUBLIC_EXPONENT:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "e", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_RSA, "e", attr);
 
 	/* RSA private key parts */
 	case CKA_PRIVATE_EXPONENT:
@@ -261,13 +263,13 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
 		return CKR_ATTRIBUTE_SENSITIVE;
 
 	case CKA_PRIME:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "p", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "p", attr);
 
 	case CKA_SUBPRIME:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "q", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "q", attr);
 
 	case CKA_BASE:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "g", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "g", attr);
 
 	/* DSA private parts */
 	case CKA_VALUE:
@@ -278,7 +280,7 @@ gck_private_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK
 }
 
 static GckSexp*
-gck_private_xsa_key_real_acquire_crypto_sexp (GckKey *base, GckSession *session)
+gck_private_xsa_key_real_acquire_crypto_sexp (GckSexpKey *base, GckSession *session)
 {
 	GckPrivateXsaKey *self = GCK_PRIVATE_XSA_KEY (base);
 	GckSexp *sexp = NULL;
@@ -328,7 +330,7 @@ gck_private_xsa_key_class_init (GckPrivateXsaKeyClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
-	GckKeyClass *key_class = GCK_KEY_CLASS (klass);
+	GckSexpKeyClass *key_class = GCK_SEXP_KEY_CLASS (klass);
 
 	gck_private_xsa_key_parent_class = g_type_class_peek_parent (klass);
 	g_type_class_add_private (klass, sizeof (GckPrivateXsaKeyPrivate));
diff --git a/pkcs11/gck/gck-private-xsa-key.h b/pkcs11/gck/gck-private-xsa-key.h
index ddc2823..1a5dbde 100644
--- a/pkcs11/gck/gck-private-xsa-key.h
+++ b/pkcs11/gck/gck-private-xsa-key.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 
-#include "gck-key.h"
+#include "gck-sexp-key.h"
 #include "gck-types.h"
 
 #define GCK_FACTORY_PRIVATE_XSA_KEY            (gck_private_xsa_key_get_factory ())
@@ -40,12 +40,12 @@ typedef struct _GckPrivateXsaKeyClass GckPrivateXsaKeyClass;
 typedef struct _GckPrivateXsaKeyPrivate GckPrivateXsaKeyPrivate;
 
 struct _GckPrivateXsaKey {
-	GckKey parent;
+	GckSexpKey parent;
 	GckPrivateXsaKeyPrivate *pv;
 };
 
 struct _GckPrivateXsaKeyClass {
-	GckKeyClass parent_class;
+	GckSexpKeyClass parent_class;
 };
 
 GType                  gck_private_xsa_key_get_type               (void);
diff --git a/pkcs11/gck/gck-public-xsa-key.c b/pkcs11/gck/gck-public-xsa-key.c
index 5cdd093..5ab32bf 100644
--- a/pkcs11/gck/gck-public-xsa-key.c
+++ b/pkcs11/gck/gck-public-xsa-key.c
@@ -24,14 +24,14 @@
 #include "pkcs11/pkcs11.h"
 
 #include "gck-attributes.h"
-#include "gck-crypto.h"
 #include "gck-factory.h"
 #include "gck-public-xsa-key.h"
 #include "gck-session.h"
+#include "gck-sexp.h"
 #include "gck-transaction.h"
 #include "gck-util.h"
 
-G_DEFINE_TYPE (GckPublicXsaKey, gck_public_xsa_key, GCK_TYPE_KEY);
+G_DEFINE_TYPE (GckPublicXsaKey, gck_public_xsa_key, GCK_TYPE_SEXP_KEY);
 
 /* -----------------------------------------------------------------------------
  * INTERNAL
@@ -45,8 +45,8 @@ return_modulus_bits (GckPublicXsaKey *self, CK_ATTRIBUTE_PTR attr)
 	int algorithm;
 	CK_RV rv;
 
-	if (!gck_crypto_sexp_parse_key (gck_sexp_get (gck_key_get_base_sexp (GCK_KEY (self))),
-	                                &algorithm, NULL, &numbers))
+	if (!gck_sexp_parse_key (gck_sexp_get (gck_sexp_key_get_base (GCK_SEXP_KEY (self))),
+	                         &algorithm, NULL, &numbers))
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
 
 	if (algorithm != GCRY_PK_RSA) {
@@ -55,7 +55,7 @@ return_modulus_bits (GckPublicXsaKey *self, CK_ATTRIBUTE_PTR attr)
 	}
 
 	g_assert (numbers);
-	if (!gck_crypto_sexp_extract_mpi (numbers, &mpi, "n", NULL))
+	if (!gck_sexp_extract_mpi (numbers, &mpi, "n", NULL))
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
 
 	gcry_sexp_release (numbers);
@@ -166,6 +166,7 @@ static CK_RV
 gck_public_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
 {
 	GckPublicXsaKey *self = GCK_PUBLIC_XSA_KEY (base);
+	gint algorithm;
 
 	switch (attr->type)
 	{
@@ -174,7 +175,8 @@ gck_public_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK_
 		return gck_attribute_set_ulong (attr, CKO_PUBLIC_KEY);
 
 	case CKA_ENCRYPT:
-		return gck_attribute_set_bool (attr, gck_key_get_algorithm (GCK_KEY (self)) == GCRY_PK_RSA);
+		algorithm = gck_sexp_key_get_algorithm (GCK_SEXP_KEY (self));
+		return gck_attribute_set_bool (attr, algorithm == GCRY_PK_RSA);
 
 	case CKA_VERIFY:
 		return gck_attribute_set_bool (attr, TRUE);
@@ -195,34 +197,34 @@ gck_public_xsa_key_real_get_attribute (GckObject *base, GckSession *session, CK_
 		return return_modulus_bits (self, attr);
 
 	case CKA_MODULUS:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "n", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_RSA, "n", attr);
 
 	case CKA_PUBLIC_EXPONENT:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_RSA, "e", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_RSA, "e", attr);
 
 	case CKA_PRIME:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "p", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "p", attr);
 
 	case CKA_SUBPRIME:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "q", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "q", attr);
 
 	case CKA_BASE:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "g", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "g", attr);
 
 	/* DSA public value */
 	case CKA_VALUE:
-		return gck_key_set_key_part (GCK_KEY (self), GCRY_PK_DSA, "y", attr);
+		return gck_sexp_key_set_part (GCK_SEXP_KEY (self), GCRY_PK_DSA, "y", attr);
 	};
 
 	return GCK_OBJECT_CLASS (gck_public_xsa_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static GckSexp*
-gck_public_xsa_key_acquire_crypto_sexp (GckKey *self, GckSession *session)
+gck_public_xsa_key_acquire_crypto_sexp (GckSexpKey *self, GckSession *session)
 {
 	GckSexp* sexp;
 
-	sexp = gck_key_get_base_sexp (self);
+	sexp = gck_sexp_key_get_base (self);
 	if (sexp != NULL)
 		gck_sexp_ref (sexp);
 
@@ -239,7 +241,7 @@ static void
 gck_public_xsa_key_class_init (GckPublicXsaKeyClass *klass)
 {
 	GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
-	GckKeyClass *key_class = GCK_KEY_CLASS (klass);
+	GckSexpKeyClass *key_class = GCK_SEXP_KEY_CLASS (klass);
 
 	gck_public_xsa_key_parent_class = g_type_class_peek_parent (klass);
 
diff --git a/pkcs11/gck/gck-public-xsa-key.h b/pkcs11/gck/gck-public-xsa-key.h
index 5cfd99a..d5f08f0 100644
--- a/pkcs11/gck/gck-public-xsa-key.h
+++ b/pkcs11/gck/gck-public-xsa-key.h
@@ -24,7 +24,7 @@
 
 #include <glib-object.h>
 
-#include "gck-key.h"
+#include "gck-sexp-key.h"
 #include "gck-types.h"
 
 #define GCK_FACTORY_PUBLIC_XSA_KEY            (gck_public_xsa_key_get_factory ())
@@ -40,12 +40,12 @@ typedef struct _GckPublicXsaKeyClass GckPublicXsaKeyClass;
 typedef struct _GckPublicXsaKeyPrivate GckPublicXsaKeyPrivate;
 
 struct _GckPublicXsaKey {
-	GckKey parent;
+	GckSexpKey parent;
 	GckPublicXsaKeyPrivate *pv;
 };
 
 struct _GckPublicXsaKeyClass {
-	GckKeyClass parent_class;
+	GckSexpKeyClass parent_class;
 };
 
 GType                     gck_public_xsa_key_get_type           (void);
diff --git a/pkcs11/gck/gck-session.c b/pkcs11/gck/gck-session.c
index 906b6ca..44c9175 100644
--- a/pkcs11/gck/gck-session.c
+++ b/pkcs11/gck/gck-session.c
@@ -27,12 +27,12 @@
 #include "gck-attributes.h"
 #include "gck-credential.h"
 #include "gck-crypto.h"
-#include "gck-key.h"
 #include "gck-factory.h"
 #include "gck-manager.h"
 #include "gck-memory-store.h"
 #include "gck-session.h"
 #include "gck-sexp.h"
+#include "gck-sexp-key.h"
 #include "gck-transaction.h"
 #include "gck-util.h"
 
@@ -73,9 +73,10 @@ struct _GckSessionPrivate {
 
 	/* Used for find operations */
 	GArray *found_objects;
-	
+
 	/* Used for crypto operations */
-	GckSexp *crypto_sexp;
+	gpointer crypto_state;
+	GDestroyNotify crypto_destroy;
 	CK_MECHANISM_TYPE crypto_mechanism;
 	CK_ATTRIBUTE_TYPE crypto_method;
 };
@@ -94,15 +95,14 @@ cleanup_crypto (GckSession *self)
 {
 	g_assert (self->pv->current_operation == cleanup_crypto);
 
-	if (self->pv->crypto_sexp) {
-		gck_sexp_unref (self->pv->crypto_sexp);
-		self->pv->crypto_sexp = NULL;
-	}
-
+	if (self->pv->crypto_state && self->pv->crypto_destroy)
+		(self->pv->crypto_destroy) (self->pv->crypto_state);
+	self->pv->crypto_state = NULL;
+	self->pv->crypto_destroy = NULL;
 	self->pv->crypto_mechanism = 0;
 	self->pv->crypto_method = 0;
 
-	g_assert (GCK_IS_KEY (self->pv->current_object));
+	g_assert (GCK_IS_OBJECT (self->pv->current_object));
 	if (self->pv->current_object)
 		g_object_unref (self->pv->current_object);
 	self->pv->current_object = NULL;
@@ -134,15 +134,15 @@ prepare_crypto (GckSession *self, CK_MECHANISM_PTR mech,
 		(self->pv->current_operation) (self);
 		g_assert (!self->pv->current_operation);
 	}
-	
-	g_assert (!self->pv->crypto_sexp);
-	
+
+	g_assert (!self->pv->crypto_state);
+
 	/* First find the object */
 	rv = gck_session_lookup_readable_object (self, handle, &object);
 	if (rv != CKR_OK)
 		return rv;
-	
-	if (!GCK_IS_KEY (object))
+
+	if (!GCK_IS_OBJECT (object))
 		return CKR_KEY_HANDLE_INVALID;
 
 	/* Lookup the mechanisms this object can do */
@@ -197,18 +197,16 @@ process_crypto (GckSession *self, CK_ATTRIBUTE_TYPE method, CK_BYTE_PTR bufone,
 	
 	if (rv == CKR_OK) {
 		/* Load up the actual sexp we're going to use */
-		if (!self->pv->crypto_sexp) {
-			g_return_val_if_fail (GCK_IS_KEY (self->pv->current_object), CKR_GENERAL_ERROR);
-			self->pv->crypto_sexp = gck_key_acquire_crypto_sexp (GCK_KEY (self->pv->current_object), self);
-			if (!self->pv->crypto_sexp)
-				rv = CKR_USER_NOT_LOGGED_IN;
+		if (!self->pv->crypto_state) {
+			g_return_val_if_fail (GCK_IS_OBJECT (self->pv->current_object), CKR_GENERAL_ERROR);
+			rv = gck_crypto_prepare (self, self->pv->crypto_mechanism, self->pv->current_object);
 		}
 	}
 
 	if (rv == CKR_OK) {
 		g_assert (self->pv->crypto_mechanism);
-		rv = gck_crypto_perform (gck_sexp_get (self->pv->crypto_sexp), self->pv->crypto_mechanism, 
-		                         method, bufone, n_bufone, buftwo, n_buftwo);
+		rv = gck_crypto_perform (self, self->pv->crypto_mechanism, method,
+		                         bufone, n_bufone, buftwo, n_buftwo);
 	}
 	
 	/* Under these conditions the operation isn't complete */
@@ -639,6 +637,26 @@ gck_session_set_logged_in (GckSession *self, gulong logged_in)
 	g_object_notify (G_OBJECT (self), "logged-in");
 }
 
+gpointer
+gck_session_get_crypto_state (GckSession *self)
+{
+	g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
+	return self->pv->crypto_state;
+}
+
+void
+gck_session_set_crypto_state (GckSession *self, gpointer state,
+                              GDestroyNotify destroy)
+{
+	g_return_if_fail (GCK_IS_SESSION (self));
+	if (self->pv->crypto_state != state) {
+		if (self->pv->crypto_state && self->pv->crypto_destroy)
+			(self->pv->crypto_destroy) (self->pv->crypto_state);
+	}
+	self->pv->crypto_state = state;
+	self->pv->crypto_destroy = destroy;
+}
+
 gboolean
 gck_session_get_read_only (GckSession *self)
 {
diff --git a/pkcs11/gck/gck-session.h b/pkcs11/gck/gck-session.h
index 62124c8..6afb563 100644
--- a/pkcs11/gck/gck-session.h
+++ b/pkcs11/gck/gck-session.h
@@ -79,6 +79,12 @@ gulong                   gck_session_get_logged_in                      (GckSess
 void                     gck_session_set_logged_in                      (GckSession *self,
                                                                          gulong logged_in);
 
+gpointer                 gck_session_get_crypto_state                   (GckSession *self);
+
+void                     gck_session_set_crypto_state                   (GckSession *self,
+                                                                         gpointer state,
+                                                                         GDestroyNotify destroy);
+
 CK_RV                    gck_session_lookup_readable_object             (GckSession *self, 
                                                                          CK_OBJECT_HANDLE handle, 
                                                                          GckObject **result);
diff --git a/pkcs11/gck/gck-key.c b/pkcs11/gck/gck-sexp-key.c
similarity index 56%
rename from pkcs11/gck/gck-key.c
rename to pkcs11/gck/gck-sexp-key.c
index 134fc7e..e899a42 100644
--- a/pkcs11/gck/gck-key.c
+++ b/pkcs11/gck/gck-sexp-key.c
@@ -1,22 +1,22 @@
-/* 
+/*
  * gnome-keyring
- * 
+ *
  * Copyright (C) 2008 Stefan Walter
- * 
- * This program is free software; you can redistribute it and/or modify 
+ *
+ * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General  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  License for more details.
- *  
- * You should have received a copy of the GNU Lesser General 
+ *
+ * You should have received a copy of the GNU Lesser General
  * License along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.  
+ * 02111-1307, USA.
  */
 
 #include "config.h"
@@ -24,8 +24,9 @@
 #include "pkcs11/pkcs11.h"
 
 #include "gck-attributes.h"
-#include "gck-crypto.h"
-#include "gck-key.h"
+#include "gck-mechanism-dsa.h"
+#include "gck-mechanism-rsa.h"
+#include "gck-sexp-key.h"
 #include "gck-util.h"
 
 enum {
@@ -34,29 +35,29 @@ enum {
 	PROP_ALGORITHM
 };
 
-struct _GckKeyPrivate {
+struct _GckSexpKeyPrivate {
 	GckSexp *base_sexp;
 };
 
-G_DEFINE_TYPE (GckKey, gck_key, GCK_TYPE_OBJECT);
+G_DEFINE_TYPE (GckSexpKey, gck_sexp_key, GCK_TYPE_OBJECT);
 
 /* -----------------------------------------------------------------------------
- * INTERNAL 
+ * INTERNAL
  */
 
 /* -----------------------------------------------------------------------------
- * KEY 
+ * KEY
  */
 
-static CK_RV 
-gck_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
+static CK_RV
+gck_sexp_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE* attr)
 {
-	GckKey *self = GCK_KEY (base);
-	
+	GckSexpKey *self = GCK_SEXP_KEY (base);
+
 	switch (attr->type) {
 	case CKA_KEY_TYPE:
 		{
-			switch (gck_key_get_algorithm (self)) {
+			switch (gck_sexp_key_get_algorithm (self)) {
 			case GCRY_PK_RSA:
 				return gck_attribute_set_ulong (attr, CKK_RSA);
 			case GCRY_PK_DSA:
@@ -66,7 +67,7 @@ gck_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE*
 			};
 		}
 		break;
-		
+
 	case CKA_ID:
 		{
 			guchar hash[20];
@@ -76,89 +77,68 @@ gck_key_real_get_attribute (GckObject *base, GckSession *session, CK_ATTRIBUTE*
 			return gck_attribute_set_data (attr, hash, sizeof (hash));
 		}
 		break;
-		
+
 	case CKA_START_DATE:
 	case CKA_END_DATE:
 		return gck_attribute_set_data (attr, "", 0);
-	
+
 	case CKA_DERIVE:
 		return gck_attribute_set_bool (attr, FALSE);
-		
+
 	case CKA_LOCAL:
 		return gck_attribute_set_bool (attr, FALSE);
-		
+
 	case CKA_KEY_GEN_MECHANISM:
 		return gck_attribute_set_ulong (attr, CK_UNAVAILABLE_INFORMATION);
-		
+
 	case CKA_ALLOWED_MECHANISMS:
-		switch (gck_key_get_algorithm (self)) {
+		switch (gck_sexp_key_get_algorithm (self)) {
 		case GCRY_PK_RSA:
-			return gck_attribute_set_data (attr, (CK_VOID_PTR)GCK_CRYPTO_RSA_MECHANISMS, 
-			                          sizeof (GCK_CRYPTO_RSA_MECHANISMS));
+			return gck_attribute_set_data (attr, (CK_VOID_PTR)GCK_CRYPTO_RSA_MECHANISMS,
+			                               sizeof (GCK_CRYPTO_RSA_MECHANISMS));
 		case GCRY_PK_DSA:
-			return gck_attribute_set_data (attr, (CK_VOID_PTR)GCK_CRYPTO_DSA_MECHANISMS, 
-			                          sizeof (GCK_CRYPTO_DSA_MECHANISMS));
+			return gck_attribute_set_data (attr, (CK_VOID_PTR)GCK_CRYPTO_DSA_MECHANISMS,
+			                               sizeof (GCK_CRYPTO_DSA_MECHANISMS));
 		default:
 			g_return_val_if_reached (CKR_GENERAL_ERROR);
 		};
-	
+
 	/* Lookup the certificate subject */
 	case CKA_SUBJECT:
 		/* TODO: When we have certificates, implement this */
 		return gck_attribute_set_data (attr, "", 0);
 	};
 
-	return GCK_OBJECT_CLASS (gck_key_parent_class)->get_attribute (base, session, attr);
-}
-
-static GObject* 
-gck_key_constructor (GType type, guint n_props, GObjectConstructParam *props) 
-{
-	GckKey *self = GCK_KEY (G_OBJECT_CLASS (gck_key_parent_class)->constructor(type, n_props, props));
-	g_return_val_if_fail (self, NULL);	
-
-
-	return G_OBJECT (self);
+	return GCK_OBJECT_CLASS (gck_sexp_key_parent_class)->get_attribute (base, session, attr);
 }
 
 static void
-gck_key_init (GckKey *self)
+gck_sexp_key_init (GckSexpKey *self)
 {
-	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_KEY, GckKeyPrivate);
-
+	self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, GCK_TYPE_SEXP_KEY, GckSexpKeyPrivate);
 }
 
 static void
-gck_key_dispose (GObject *obj)
+gck_sexp_key_finalize (GObject *obj)
 {
-#if 0
-	GckKey *self = GCK_KEY (obj);
-#endif
-	
-	G_OBJECT_CLASS (gck_key_parent_class)->dispose (obj);
-}
+	GckSexpKey *self = GCK_SEXP_KEY (obj);
 
-static void
-gck_key_finalize (GObject *obj)
-{
-	GckKey *self = GCK_KEY (obj);
-	
 	if (self->pv->base_sexp)
 		gck_sexp_unref (self->pv->base_sexp);
 	self->pv->base_sexp = NULL;
 
-	G_OBJECT_CLASS (gck_key_parent_class)->finalize (obj);
+	G_OBJECT_CLASS (gck_sexp_key_parent_class)->finalize (obj);
 }
 
 static void
-gck_key_set_property (GObject *obj, guint prop_id, const GValue *value, 
+gck_sexp_key_set_property (GObject *obj, guint prop_id, const GValue *value,
                       GParamSpec *pspec)
 {
-	GckKey *self = GCK_KEY (obj);
-	
+	GckSexpKey *self = GCK_SEXP_KEY (obj);
+
 	switch (prop_id) {
 	case PROP_BASE_SEXP:
-		gck_key_set_base_sexp (self, g_value_get_boxed (value));
+		gck_sexp_key_set_base (self, g_value_get_boxed (value));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -167,17 +147,17 @@ gck_key_set_property (GObject *obj, guint prop_id, const GValue *value,
 }
 
 static void
-gck_key_get_property (GObject *obj, guint prop_id, GValue *value, 
+gck_sexp_key_get_property (GObject *obj, guint prop_id, GValue *value,
                       GParamSpec *pspec)
 {
-	GckKey *self = GCK_KEY (obj);
-	
+	GckSexpKey *self = GCK_SEXP_KEY (obj);
+
 	switch (prop_id) {
 	case PROP_BASE_SEXP:
-		g_value_set_boxed (value, gck_key_get_base_sexp (self));
+		g_value_set_boxed (value, gck_sexp_key_get_base (self));
 		break;
 	case PROP_ALGORITHM:
-		g_value_set_int (value, gck_key_get_algorithm (self));
+		g_value_set_int (value, gck_sexp_key_get_algorithm (self));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
@@ -186,36 +166,27 @@ gck_key_get_property (GObject *obj, guint prop_id, GValue *value,
 }
 
 static void
-gck_key_class_init (GckKeyClass *klass)
+gck_sexp_key_class_init (GckSexpKeyClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
-	
-	gck_key_parent_class = g_type_class_peek_parent (klass);
-	g_type_class_add_private (klass, sizeof (GckKeyPrivate));
-
-	gobject_class->constructor = gck_key_constructor;
-	gobject_class->dispose = gck_key_dispose;
-	gobject_class->finalize = gck_key_finalize;
-	gobject_class->set_property = gck_key_set_property;
-	gobject_class->get_property = gck_key_get_property;
-	
-	gck_class->get_attribute = gck_key_real_get_attribute;
-    
+
+	gck_sexp_key_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (GckSexpKeyPrivate));
+
+	gobject_class->finalize = gck_sexp_key_finalize;
+	gobject_class->set_property = gck_sexp_key_set_property;
+	gobject_class->get_property = gck_sexp_key_get_property;
+
+	gck_class->get_attribute = gck_sexp_key_real_get_attribute;
+
 	g_object_class_install_property (gobject_class, PROP_BASE_SEXP,
-	           g_param_spec_boxed ("base-sexp", "Base S-Exp", "Base Key S-Expression", 
+	           g_param_spec_boxed ("base-sexp", "Base S-Exp", "Base Key S-Expression",
 	                               GCK_BOXED_SEXP, G_PARAM_READWRITE));
-	
+
 	g_object_class_install_property (gobject_class, PROP_ALGORITHM,
-	           g_param_spec_int ("algorithm", "Algorithm", "GCrypt Algorithm", 
+	           g_param_spec_int ("algorithm", "Algorithm", "GCrypt Algorithm",
 	                             0, G_MAXINT, 0, G_PARAM_READABLE));
-    
-#if 0
-	signals[SIGNAL] = g_signal_new ("signal", GCK_TYPE_KEY, 
-	                                G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GckKeyClass, signal),
-	                                NULL, NULL, g_cclosure_marshal_VOID__OBJECT, 
-	                                G_TYPE_NONE, 0);
-#endif
 }
 
 /* -----------------------------------------------------------------------------
@@ -223,16 +194,16 @@ gck_key_class_init (GckKeyClass *klass)
  */
 
 GckSexp*
-gck_key_get_base_sexp (GckKey *self)
+gck_sexp_key_get_base (GckSexpKey *self)
 {
-	g_return_val_if_fail (GCK_IS_KEY (self), NULL);
+	g_return_val_if_fail (GCK_IS_SEXP_KEY (self), NULL);
 	return self->pv->base_sexp;
 }
 
 void
-gck_key_set_base_sexp (GckKey *self, GckSexp *sexp)
+gck_sexp_key_set_base (GckSexpKey *self, GckSexp *sexp)
 {
-	g_return_if_fail (GCK_IS_KEY (self));
+	g_return_if_fail (GCK_IS_SEXP_KEY (self));
 	if (sexp)
 		gck_sexp_ref (sexp);
 	if (self->pv->base_sexp)
@@ -243,50 +214,48 @@ gck_key_set_base_sexp (GckKey *self, GckSexp *sexp)
 }
 
 int
-gck_key_get_algorithm (GckKey *self) 
+gck_sexp_key_get_algorithm (GckSexpKey *self)
 {
 	int algorithm;
 	g_return_val_if_fail (self->pv->base_sexp, 0);
-	if (!gck_crypto_sexp_parse_key (gck_sexp_get (self->pv->base_sexp), &algorithm, NULL, NULL))
+	if (!gck_sexp_parse_key (gck_sexp_get (self->pv->base_sexp), &algorithm, NULL, NULL))
 		g_return_val_if_reached (0);
 	return algorithm;
 }
 
 CK_RV
-gck_key_set_key_part (GckKey *self, int algo, const char *part,
-                      CK_ATTRIBUTE_PTR attr)
+gck_sexp_key_set_part (GckSexpKey *self, int algo, const char *part, CK_ATTRIBUTE_PTR attr)
 {
 	gcry_sexp_t numbers;
 	gcry_mpi_t mpi;
 	int algorithm;
 	CK_RV rv;
-	
-	g_return_val_if_fail (GCK_IS_KEY (self), CKR_GENERAL_ERROR);
+
+	g_return_val_if_fail (GCK_IS_SEXP_KEY (self), CKR_GENERAL_ERROR);
 	g_return_val_if_fail (self->pv->base_sexp, CKR_GENERAL_ERROR);
-	
-	if (!gck_crypto_sexp_parse_key (gck_sexp_get (self->pv->base_sexp),
+
+	if (!gck_sexp_parse_key (gck_sexp_get (self->pv->base_sexp),
 	                                &algorithm, NULL, &numbers))
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
-	
+
 	if (algorithm != algo) {
 		gcry_sexp_release (numbers);
 		return CKR_ATTRIBUTE_TYPE_INVALID;
 	}
-	
-	if (!gck_crypto_sexp_extract_mpi (numbers, &mpi, part, NULL))
+
+	if (!gck_sexp_extract_mpi (numbers, &mpi, part, NULL))
 		g_return_val_if_reached (CKR_GENERAL_ERROR);
 	rv = gck_attribute_set_mpi (attr, mpi);
 	gcry_sexp_release (numbers);
 	gcry_mpi_release (mpi);
-	
+
 	return rv;
 }
 
 GckSexp*
-gck_key_acquire_crypto_sexp (GckKey *self, GckSession *session)
+gck_sexp_key_acquire_crypto_sexp (GckSexpKey *self, GckSession *session)
 {
-	g_return_val_if_fail (GCK_IS_KEY (self), NULL);
-	g_return_val_if_fail (GCK_KEY_GET_CLASS (self)->acquire_crypto_sexp, NULL);
-	return GCK_KEY_GET_CLASS (self)->acquire_crypto_sexp (self, session);
+	g_return_val_if_fail (GCK_IS_SEXP_KEY (self), NULL);
+	g_return_val_if_fail (GCK_SEXP_KEY_GET_CLASS (self)->acquire_crypto_sexp, NULL);
+	return GCK_SEXP_KEY_GET_CLASS (self)->acquire_crypto_sexp (self, session);
 }
-
diff --git a/pkcs11/gck/gck-sexp-key.h b/pkcs11/gck/gck-sexp-key.h
new file mode 100644
index 0000000..05160e4
--- /dev/null
+++ b/pkcs11/gck/gck-sexp-key.h
@@ -0,0 +1,71 @@
+/*
+ * gnome-sexp_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  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  License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * 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 __GCK_SEXP_KEY_H__
+#define __GCK_SEXP_KEY_H__
+
+#include <glib-object.h>
+
+#include "gck-sexp.h"
+#include "gck-object.h"
+#include "gck-types.h"
+
+#define GCK_TYPE_SEXP_KEY               (gck_sexp_key_get_type ())
+#define GCK_SEXP_KEY(obj)               (G_TYPE_CHECK_INSTANCE_CAST ((obj), GCK_TYPE_SEXP_KEY, GckSexpKey))
+#define GCK_SEXP_KEY_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GCK_TYPE_SEXP_KEY, GckSexpKeyClass))
+#define GCK_IS_SEXP_KEY(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GCK_TYPE_SEXP_KEY))
+#define GCK_IS_SEXP_KEY_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCK_TYPE_SEXP_KEY))
+#define GCK_SEXP_KEY_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCK_TYPE_SEXP_KEY, GckSexpKeyClass))
+
+typedef struct _GckSexpKeyClass GckSexpKeyClass;
+typedef struct _GckSexpKeyPrivate GckSexpKeyPrivate;
+
+struct _GckSexpKey {
+	GckObject parent;
+	GckSexpKeyPrivate *pv;
+};
+
+struct _GckSexpKeyClass {
+	GckObjectClass parent_class;
+
+	/* virtual methods */
+
+	GckSexp* (*acquire_crypto_sexp) (GckSexpKey *self, GckSession *session);
+};
+
+GType                gck_sexp_key_get_type                (void);
+
+GckSexp*             gck_sexp_key_get_base                (GckSexpKey *self);
+
+void                 gck_sexp_key_set_base                (GckSexpKey *self,
+                                                           GckSexp *sexp);
+
+int                  gck_sexp_key_get_algorithm           (GckSexpKey *self);
+
+CK_RV                gck_sexp_key_set_part                (GckSexpKey *self,
+                                                           int algorithm,
+                                                           const char *part,
+                                                           CK_ATTRIBUTE_PTR attr);
+
+GckSexp*             gck_sexp_key_acquire_crypto_sexp     (GckSexpKey *self,
+                                                           GckSession *session);
+
+#endif /* __GCK_SEXP_KEY_H__ */
diff --git a/pkcs11/gck/gck-sexp.c b/pkcs11/gck/gck-sexp.c
index a15549d..a8d8ae0 100644
--- a/pkcs11/gck/gck-sexp.c
+++ b/pkcs11/gck/gck-sexp.c
@@ -77,3 +77,206 @@ gck_sexp_boxed_type (void)
 		                                     (GBoxedFreeFunc)gck_sexp_unref);
 	return type;
 }
+
+#define PUBLIC_KEY "public-key"
+#define PUBLIC_KEY_L 10
+#define PRIVATE_KEY "private-key"
+#define PRIVATE_KEY_L 11
+
+gboolean
+gck_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;
+
+	data = gcry_sexp_nth_data (child, 0, &n_data);
+	if (!data)
+		goto done;
+
+	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_sexp_extract_mpi (rsa, &n, "n", NULL) ||
+	    !gck_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_sexp_extract_mpi (dsa, &p, "p", NULL) ||
+	    !gck_sexp_extract_mpi (dsa, &q, "q", NULL) ||
+	    !gck_sexp_extract_mpi (dsa, &g, "g", NULL) ||
+	    !gck_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_sexp_key_to_public (gcry_sexp_t privkey, gcry_sexp_t *pubkey)
+{
+	gcry_sexp_t numbers;
+	int algorithm;
+
+	if (!gck_sexp_parse_key (privkey, &algorithm, NULL, &numbers))
+		g_return_val_if_reached (FALSE);
+
+	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_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 = gck_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;
+}
+
+gcry_sexp_t
+gck_sexp_get_childv (gcry_sexp_t sexp, va_list va)
+{
+	gcry_sexp_t at = NULL;
+	gcry_sexp_t child;
+	const char *name;
+
+	g_assert (sexp);
+	g_assert (va);
+
+	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;
+}
+
+void
+gck_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);
+}
diff --git a/pkcs11/gck/gck-sexp.h b/pkcs11/gck/gck-sexp.h
index e3f9089..1bfd463 100644
--- a/pkcs11/gck/gck-sexp.h
+++ b/pkcs11/gck/gck-sexp.h
@@ -40,4 +40,22 @@ gcry_sexp_t    gck_sexp_get           (GckSexp *sexp);
 
 GType          gck_sexp_boxed_type    (void);
 
-#endif /* GCKSEXPHANDLE_H_ */
+
+gboolean       gck_sexp_parse_key                (gcry_sexp_t sexp,
+                                                  int *algorithm,
+                                                  gboolean *is_private,
+                                                  gcry_sexp_t *numbers);
+
+gboolean       gck_sexp_key_to_public            (gcry_sexp_t sexp,
+                                                  gcry_sexp_t *pub);
+
+gboolean       gck_sexp_extract_mpi              (gcry_sexp_t sexp,
+                                                  gcry_mpi_t *mpi,
+                                                  ...) G_GNUC_NULL_TERMINATED;
+
+gcry_sexp_t    gck_sexp_get_childv               (gcry_sexp_t sexp,
+                                                  va_list va);
+
+void           gck_sexp_dump                     (gcry_sexp_t sexp);
+
+#endif /* GCKSEXP_H_ */
diff --git a/pkcs11/gck/gck-types.h b/pkcs11/gck/gck-types.h
index 034214b..5ad1c76 100644
--- a/pkcs11/gck/gck-types.h
+++ b/pkcs11/gck/gck-types.h
@@ -26,7 +26,6 @@ typedef struct _GckCertificate GckCertificate;
 typedef struct _GckCertificateKey GckCertificateKey;
 typedef struct _GckCertificateTrust GckCertificateTrust;
 typedef struct _GckCredential GckCredential;
-typedef struct _GckKey GckKey;
 typedef struct _GckFactory GckFactory;
 typedef struct _GckManager GckManager;
 typedef struct _GckModule GckModule;
@@ -38,6 +37,7 @@ typedef struct _GckSession GckSession;
 typedef struct _GckSessionPrivateKey GckSessionPrivateKey;
 typedef struct _GckSessionPublicKey GckSessionPublicKey;
 typedef struct _GckSexp GckSexp;
+typedef struct _GckSexpKey GckSexpKey;
 typedef struct _GckStore GckStore;
 typedef struct _GckTimer GckTimer;
 typedef struct _GckTransaction GckTransaction;
diff --git a/pkcs11/gck/tests/Makefile.am b/pkcs11/gck/tests/Makefile.am
index 1f82931..1a16b2b 100644
--- a/pkcs11/gck/tests/Makefile.am
+++ b/pkcs11/gck/tests/Makefile.am
@@ -5,7 +5,7 @@ asn1-def-test.h: test.asn
 # Test files should be listed in order they need to run
 UNIT_AUTO = \
 	unit-test-attributes.c \
-	unit-test-crypto.c \
+	unit-test-sexp.c \
 	unit-test-data-asn1.c \
 	unit-test-data-der.c \
 	unit-test-object.c \
diff --git a/pkcs11/gck/tests/unit-test-data-der.c b/pkcs11/gck/tests/unit-test-data-der.c
index 46804f5..412f2cf 100644
--- a/pkcs11/gck/tests/unit-test-data-der.c
+++ b/pkcs11/gck/tests/unit-test-data-der.c
@@ -28,6 +28,7 @@
 #include "gck/gck-crypto.h"
 #include "gck/gck-data-asn1.h"
 #include "gck/gck-data-der.h"
+#include "gck/gck-sexp.h"
 
 #include "egg/egg-openssl.h"
 
@@ -425,7 +426,7 @@ DEFINE_TEST(read_all_pkcs8)
 		res = gck_data_der_read_private_pkcs8 (data, n_data, "booo", 4, &sexp);
 		g_assert (res == GCK_DATA_SUCCESS);
 		
-		g_assert (gck_crypto_sexp_parse_key (sexp, NULL, NULL, NULL));
+		g_assert (gck_sexp_parse_key (sexp, NULL, NULL, NULL));
 		gcry_sexp_release (sexp);
 		g_free (data);
 	}
diff --git a/pkcs11/gck/tests/unit-test-crypto.c b/pkcs11/gck/tests/unit-test-sexp.c
similarity index 93%
rename from pkcs11/gck/tests/unit-test-crypto.c
rename to pkcs11/gck/tests/unit-test-sexp.c
index 457306f..1136fc1 100644
--- a/pkcs11/gck/tests/unit-test-crypto.c
+++ b/pkcs11/gck/tests/unit-test-sexp.c
@@ -1,5 +1,5 @@
 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* unit-test-crypto.c: Test crypto stuff
+/* unit-test-sexp.c: Test sexp stuff
 
    Copyright (C) 2007 Stefan Walter
 
@@ -28,6 +28,7 @@
 #include "run-auto-test.h"
 
 #include "gck/gck-crypto.h"
+#include "gck/gck-sexp.h"
 
 #include <gcrypt.h>
 
@@ -55,9 +56,9 @@ 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);
@@ -79,15 +80,15 @@ DEFINE_TEST(parse_key)
 	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);
+	ret = gck_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);
+
+	ret = gck_sexp_extract_mpi (rsakey, &mpi, "p", NULL);
 	g_assert (ret);
 	g_assert (mpi != NULL);
 }
@@ -98,34 +99,34 @@ DEFINE_TEST(sexp_key_to_public)
 	guchar id1[20], id2[20];
 	gboolean ret;
 	guchar *p;
-	
+
 	/* RSA */
-	ret = gck_crypto_sexp_key_to_public (rsakey, &pubkey);
+	ret = gck_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);
+	ret = gck_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);
 
 }
diff --git a/pkcs11/ssh-store/gck-ssh-private-key.c b/pkcs11/ssh-store/gck-ssh-private-key.c
index 3b4a0d7..eb28786 100644
--- a/pkcs11/ssh-store/gck-ssh-private-key.c
+++ b/pkcs11/ssh-store/gck-ssh-private-key.c
@@ -108,8 +108,8 @@ realize_and_take_data (GckSshPrivateKey *self, gcry_sexp_t sexp, gchar *comment,
 
 	/* The base public key gets setup. */
 	wrapper = gck_sexp_new (sexp);
-	gck_key_set_base_sexp (GCK_KEY (self), wrapper);
-	gck_key_set_base_sexp (GCK_KEY (self->pubkey), wrapper);
+	gck_sexp_key_set_base (GCK_SEXP_KEY (self), wrapper);
+	gck_sexp_key_set_base (GCK_SEXP_KEY (self->pubkey), wrapper);
 	gck_sexp_unref (wrapper);
 
 	/* Own the comment */
diff --git a/pkcs11/ssh-store/tests/p11-tests.conf b/pkcs11/ssh-store/tests/p11-tests.conf
index fbc86d5..1578a78 100644
--- a/pkcs11/ssh-store/tests/p11-tests.conf
+++ b/pkcs11/ssh-store/tests/p11-tests.conf
@@ -1,3 +1,3 @@
-# Configuration for running p11-tests on this module 
-init-string = directory='test-data' 
-login-context-pin = password 
+# Configuration for running p11-tests on this module
+init-string = directory='pkcs11/ssh-store/tests/test-data'
+login-context-pin = password
diff --git a/pkcs11/ssh-store/tests/unit-test-ssh-openssh.c b/pkcs11/ssh-store/tests/unit-test-ssh-openssh.c
index 121245c..3b27120 100644
--- a/pkcs11/ssh-store/tests/unit-test-ssh-openssh.c
+++ b/pkcs11/ssh-store/tests/unit-test-ssh-openssh.c
@@ -27,7 +27,7 @@
 
 #include "gck-ssh-openssh.h"
 
-#include "gck/gck-crypto.h"
+#include "gck/gck-sexp.h"
 
 #include <glib.h>
 
@@ -70,8 +70,8 @@ DEFINE_TEST(parse_public)
 			g_warning ("couldn't parse public key: %s", PUBLIC_FILES[i]);
 			g_assert_cmpint (res, ==, GCK_DATA_SUCCESS);
 		}
-		
-		if (!gck_crypto_sexp_parse_key (sexp, &algorithm, &is_private, NULL))
+
+		if (!gck_sexp_parse_key (sexp, &algorithm, &is_private, NULL))
 			g_assert_not_reached ();
 		
 		g_assert_cmpstr (comment, ==, COMMENT);
@@ -104,8 +104,8 @@ DEFINE_TEST(parse_private)
 			g_warning ("couldn't parse private key: %s", PRIVATE_FILES[i]);
 			g_assert_cmpint (res, ==, GCK_DATA_SUCCESS);
 		}
-		
-		if (!gck_crypto_sexp_parse_key (sexp, &algorithm, &is_private, NULL))
+
+		if (!gck_sexp_parse_key (sexp, &algorithm, &is_private, NULL))
 			g_assert_not_reached ();
 		
 		g_assert_cmpint (algorithm, !=, 0);
diff --git a/pkcs11/user-store/gck-user-private-key.c b/pkcs11/user-store/gck-user-private-key.c
index 93ee0be..c6bff36 100644
--- a/pkcs11/user-store/gck-user-private-key.c
+++ b/pkcs11/user-store/gck-user-private-key.c
@@ -102,7 +102,7 @@ gck_user_private_key_real_get_attribute (GckObject *base, GckSession *session, C
 }
 
 static GckSexp* 
-gck_user_private_key_real_acquire_crypto_sexp (GckKey *base, GckSession *unused)
+gck_user_private_key_real_acquire_crypto_sexp (GckSexpKey *base, GckSession *unused)
 {
 	GckUserPrivateKey *self = GCK_USER_PRIVATE_KEY (base);
 	gcry_sexp_t sexp;
@@ -187,8 +187,8 @@ gck_user_private_key_class_init (GckUserPrivateKeyClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckObjectClass *gck_class = GCK_OBJECT_CLASS (klass);
-	GckKeyClass *key_class = GCK_KEY_CLASS (klass);
-	
+	GckSexpKeyClass *key_class = GCK_SEXP_KEY_CLASS (klass);
+
 	gobject_class->dispose = gck_user_private_key_dispose;
 	gobject_class->finalize = gck_user_private_key_finalize;
 	gobject_class->set_property = gck_user_private_key_set_property;
@@ -248,12 +248,12 @@ gck_user_private_key_real_load (GckSerializable *base, GckSecret *login, const g
 	}
 	
 	/* Calculate a public key as our 'base' */
-	if (!gck_crypto_sexp_key_to_public (sexp, &pub))
+	if (!gck_sexp_key_to_public (sexp, &pub))
 		g_return_val_if_reached (FALSE);
 	
 	/* Keep the public part of the key around for answering queries */
 	wrapper = gck_sexp_new (pub);
-	gck_key_set_base_sexp (GCK_KEY (self), wrapper);
+	gck_sexp_key_set_base (GCK_SEXP_KEY (self), wrapper);
 	gck_sexp_unref (wrapper);
 	
 	/* Encrypted private key, keep login and data */
@@ -297,7 +297,7 @@ gck_user_private_key_real_save (GckSerializable *base, GckSecret *login, guchar
 	g_return_val_if_fail (data, FALSE);
 	g_return_val_if_fail (n_data, FALSE);
 	
-	sexp = gck_user_private_key_real_acquire_crypto_sexp (GCK_KEY (self), NULL);
+	sexp = gck_user_private_key_real_acquire_crypto_sexp (GCK_SEXP_KEY (self), NULL);
 	g_return_val_if_fail (sexp, FALSE);
 	
 	password = gck_secret_get_password (login, &n_password);
diff --git a/pkcs11/user-store/gck-user-public-key.c b/pkcs11/user-store/gck-user-public-key.c
index 0eef087..6f7e255 100644
--- a/pkcs11/user-store/gck-user-public-key.c
+++ b/pkcs11/user-store/gck-user-public-key.c
@@ -145,7 +145,7 @@ gck_user_public_key_real_load (GckSerializable *base, GckSecret *login, const gu
 	}
 
 	wrapper = gck_sexp_new (sexp);
-	gck_key_set_base_sexp (GCK_KEY (self), wrapper);
+	gck_sexp_key_set_base (GCK_SEXP_KEY (self), wrapper);
 	gck_sexp_unref (wrapper);
 	
 	return TRUE;
@@ -161,7 +161,7 @@ gck_user_public_key_real_save (GckSerializable *base, GckSecret *login, guchar *
 	g_return_val_if_fail (data, FALSE);
 	g_return_val_if_fail (n_data, FALSE);
 
-	wrapper = gck_key_get_base_sexp (GCK_KEY (self));
+	wrapper = gck_sexp_key_get_base (GCK_SEXP_KEY (self));
 	g_return_val_if_fail (wrapper, FALSE);
 	
 	*data = gck_data_der_write_public_key (gck_sexp_get (wrapper), n_data);



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