gnome-keyring r1032 - in trunk: . pk pk/tests pkix pkix/tests pkix/tests/test-data po



Author: nnielsen
Date: Sun Feb  3 01:28:43 2008
New Revision: 1032
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1032&view=rev

Log:
	* pk/gkr-pk-cert.c:
	* pk/gkr-pk-netscape-trust.c:
	* pk/gkr-pk-object-storage.c:
	* pk/gkr-pk-object.c:
	* pk/gkr-pk-object.h:
	* pk/gkr-pk-privkey.c:
	* pk/gkr-pk-pubkey.c:
	* pk/tests/unit-test-pk-cert.c:
	* pk/tests/unit-test-pk-key.c:
	* pk/tests/unit-test-pk-netscape-trust.c:
	* pkix/Makefile.am:
	* pkix/gkr-pkix-asn1.c:
	* pkix/gkr-pkix-asn1.h:
	* pkix/gkr-pkix-der.c:
	* pkix/gkr-pkix-der.h:
	* pkix/gkr-pkix-openssl.c:
	* pkix/gkr-pkix-openssl.h:
	* pkix/gkr-pkix-parser.c:
	* pkix/gkr-pkix-parser.h:
	* pkix/gkr-pkix-serialize.c: (added)
	* pkix/gkr-pkix-serialize.h: (added)
	* pkix/gkr-pkix-types.h: (added)
	* pkix/tests/Makefile.am:
	* pkix/tests/unit-test-pkix-der.c:
	* pkix/tests/unit-test-pkix-parser.c:
	* pkix/tests/unit-test-pkix-serialize.c: (added)
	* pkix/tests/test-data/der-certificate.crt: (added) Reworked 
pkix parsing
	and added some serializing capabilities. Add basic 
infrastructure for
	serializing of objects like certificates and keys.



Added:
   trunk/pkix/gkr-pkix-serialize.c
   trunk/pkix/gkr-pkix-serialize.h
   trunk/pkix/gkr-pkix-types.h
   trunk/pkix/tests/test-data/der-certificate.crt   (contents, props changed)
   trunk/pkix/tests/unit-test-pkix-serialize.c
Modified:
   trunk/ChangeLog
   trunk/pk/gkr-pk-cert.c
   trunk/pk/gkr-pk-netscape-trust.c
   trunk/pk/gkr-pk-object-storage.c
   trunk/pk/gkr-pk-object.c
   trunk/pk/gkr-pk-object.h
   trunk/pk/gkr-pk-privkey.c
   trunk/pk/gkr-pk-pubkey.c
   trunk/pk/tests/unit-test-pk-cert.c
   trunk/pk/tests/unit-test-pk-key.c
   trunk/pk/tests/unit-test-pk-netscape-trust.c
   trunk/pkix/Makefile.am
   trunk/pkix/gkr-pkix-asn1.c
   trunk/pkix/gkr-pkix-asn1.h
   trunk/pkix/gkr-pkix-der.c
   trunk/pkix/gkr-pkix-der.h
   trunk/pkix/gkr-pkix-openssl.c
   trunk/pkix/gkr-pkix-openssl.h
   trunk/pkix/gkr-pkix-parser.c
   trunk/pkix/gkr-pkix-parser.h
   trunk/pkix/tests/Makefile.am
   trunk/pkix/tests/unit-test-pkix-der.c
   trunk/pkix/tests/unit-test-pkix-parser.c
   trunk/po/ChangeLog
   trunk/po/POTFILES.in

Modified: trunk/pk/gkr-pk-cert.c
==============================================================================
--- trunk/pk/gkr-pk-cert.c	(original)
+++ trunk/pk/gkr-pk-cert.c	Sun Feb  3 01:28:43 2008
@@ -145,7 +145,7 @@
 {
 	gcry_sexp_t s_key = NULL;
 	GkrPkObject *obj;
-	GkrParseResult res;
+	GkrPkixResult res;
 	guchar *data;
 	gsize n_data;
 
@@ -164,7 +164,7 @@
 	res = gkr_pkix_der_read_public_key_info (data, n_data, &s_key);
 	g_free (data);
 	
-	if (res != GKR_PARSE_SUCCESS) {
+	if (res != GKR_PKIX_SUCCESS) {
 		g_warning ("invalid public-key in certificate: %s", g_quark_to_string (obj->location));
 		return NULL;
 	}
@@ -240,7 +240,7 @@
 lookup_certificate_purposes (GkrPkCert *cert, GQuark **oids)
 {
 	GkrPkObject *obj = GKR_PK_OBJECT (cert);
-	GkrParseResult res;
+	GkrPkixResult res;
 	guchar *extension;
 	gsize n_extension;
 	CK_RV ret;
@@ -265,7 +265,7 @@
 		res = gkr_pkix_der_read_enhanced_usage (extension, n_extension, oids);
 		g_free (extension);
 	
-		if (res != GKR_PARSE_SUCCESS) {
+		if (res != GKR_PKIX_SUCCESS) {
 			g_warning ("invalid enhanced usage in certificate");
 			return CKR_GENERAL_ERROR;
 		}
@@ -354,7 +354,7 @@
 
 		/* See if it's the same */
 		name = g_strdup_printf ("tbsCertificate.extensions.?%u.extnID", i);
-		exoid = gkr_pkix_asn1_read_quark (cert->data->asn1, name);
+		exoid = gkr_pkix_asn1_read_oid (cert->data->asn1, name);
 		g_free (name);
 
 		if(exoid == oid)
@@ -468,12 +468,12 @@
 		value = 0; /* unknown */
 		data = gkr_pk_cert_get_extension (cert, OID_BASIC_CONSTRAINTS, &n_data, NULL);
 		if (data) {
-			GkrParseResult res;
+			GkrPkixResult res;
 			gboolean is_ca;
 
 			res = gkr_pkix_der_read_basic_constraints (data, n_data, &is_ca, NULL);
 			g_free (data);
-			if (res != GKR_PARSE_SUCCESS)
+			if (res != GKR_PKIX_SUCCESS)
 				return CKR_GENERAL_ERROR;
 			if (is_ca)
 				value = 2; /* authority */
@@ -586,6 +586,21 @@
 	return GKR_PK_OBJECT_CLASS (gkr_pk_cert_parent_class)->get_attribute (obj, attr);
 }
 
+static guchar*
+gkr_pk_cert_serialize (GkrPkObject *obj, const gchar *password, gsize *n_data)
+{
+	GkrPkCert *cert = GKR_PK_CERT (obj);
+
+	if (load_certificate (cert) != CKR_OK)
+		return NULL;
+
+	g_return_val_if_fail (cert->data->raw, NULL);
+	g_return_val_if_fail (cert->data->n_raw, NULL);
+	
+	*n_data = cert->data->n_raw;
+	return g_memdup	(cert->data->raw, cert->data->n_raw);
+}
+
 static void
 gkr_pk_cert_finalize (GObject *obj)
 {
@@ -616,6 +631,7 @@
 	
 	parent_class = GKR_PK_OBJECT_CLASS (klass);
 	parent_class->get_attribute = gkr_pk_cert_get_attribute;
+	parent_class->serialize = gkr_pk_cert_serialize;
 	
 	gobject_class->get_property = gkr_pk_cert_get_property;
 	gobject_class->set_property = gkr_pk_cert_set_property;
@@ -678,7 +694,7 @@
 	g_return_val_if_fail (attr->pValue, CKR_GENERAL_ERROR);
 	g_return_val_if_fail (attr->ulValueLen, CKR_GENERAL_ERROR);
 	
-	if (gkr_pkix_der_read_certificate (attr->pValue, attr->ulValueLen, &asn) != GKR_PARSE_SUCCESS)
+	if (gkr_pkix_der_read_certificate (attr->pValue, attr->ulValueLen, &asn) != GKR_PKIX_SUCCESS)
 		return CKR_ATTRIBUTE_VALUE_INVALID;
 	
 	/* All the attributes that we used up */	

Modified: trunk/pk/gkr-pk-netscape-trust.c
==============================================================================
--- trunk/pk/gkr-pk-netscape-trust.c	(original)
+++ trunk/pk/gkr-pk-netscape-trust.c	Sun Feb  3 01:28:43 2008
@@ -84,7 +84,7 @@
 static CK_RV
 has_key_usage (GkrPkNetscapeTrust *trust, guint check, CK_ULONG *val)
 {
-	GkrParseResult res;
+	GkrPkixResult res;
 	guchar *extension;
 	gsize n_extension;
 	guint usage;
@@ -101,7 +101,7 @@
 	res = gkr_pkix_der_read_key_usage (extension, n_extension, &usage);
 	g_free (extension);
 	
-	if (res != GKR_PARSE_SUCCESS) {
+	if (res != GKR_PKIX_SUCCESS) {
 		g_warning ("invalid key usage in certificate");
 		return CKR_GENERAL_ERROR;
 	}

Modified: trunk/pk/gkr-pk-object-storage.c
==============================================================================
--- trunk/pk/gkr-pk-object-storage.c	(original)
+++ trunk/pk/gkr-pk-object-storage.c	Sun Feb  3 01:28:43 2008
@@ -90,7 +90,7 @@
 
 static gchar* 
 parser_ask_password (GkrPkixParser *parser, GQuark loc, gkrunique unique, 
-                     GkrParsedType type, const gchar *label, guint failures,
+                     GQuark type, const gchar *label, guint failures,
                      ParseContext *ctx)
 {
  	GkrPkObjectStoragePrivate *pv = GKR_PK_OBJECT_STORAGE_GET_PRIVATE (ctx->storage);
@@ -131,8 +131,8 @@
 	 */
 	stype = gkr_pk_index_get_string_full (loc, unique, "parsed-type");
 	if (stype) {
-		if (type == GKR_PARSED_UNKNOWN)
-			type = gkr_pkix_parsed_type_from_string (stype);
+		if (!type && stype[0])
+			type = g_quark_from_string (stype);
 		have_indexed = TRUE;
 		g_free (stype);
 	}
@@ -148,7 +148,7 @@
 	custom_label = NULL;
 	
 	/* We have no idea what kind of data it is, poor user */
-	if (type == GKR_PARSED_UNKNOWN) {
+	if (!type) {
 		display_type = NULL;
 		title = g_strdup (_("Unlock"));
 		primary = g_strdup (_("Enter password to unlock"));
@@ -312,7 +312,7 @@
 
 static GkrPkObject*
 prepare_object (GkrPkObjectStorage *storage, GQuark location, 
-                gkrconstunique unique, GkrParsedType type)
+                gkrconstunique unique, GQuark type)
 {
 	GkrPkObjectStoragePrivate *pv = GKR_PK_OBJECT_STORAGE_GET_PRIVATE (storage);
 	GkrPkObjectManager *manager;
@@ -329,17 +329,14 @@
 		return object;
 	} 
 	
-	switch (type) {
-	case GKR_PARSED_PRIVATE_KEY:
+	if (type == GKR_PKIX_PRIVATE_KEY) 
 		gtype = GKR_TYPE_PK_PRIVKEY;
-		break;
-	case GKR_PARSED_CERTIFICATE:
+	else if (type == GKR_PKIX_PUBLIC_KEY) 
+		gtype = GKR_TYPE_PK_PUBKEY;
+	else if (type == GKR_PKIX_CERTIFICATE)
 		gtype = GKR_TYPE_PK_CERT;
-		break;
-	default:
+	else 
 		g_return_val_if_reached (NULL);
-		break;
-	}
 	
 	object = g_object_new (gtype, "manager", manager, "location", location, 
 	                       "unique", unique, NULL);
@@ -355,21 +352,21 @@
 
 static void 
 parser_parsed_partial (GkrPkixParser *parser, GQuark location, gkrunique unique,
-                       GkrParsedType type, ParseContext *ctx)
+                       GQuark type, ParseContext *ctx)
 {
  	GkrPkObjectStoragePrivate *pv = GKR_PK_OBJECT_STORAGE_GET_PRIVATE (ctx->storage);
  	GkrPkObject *object;
  	gchar *stype;
  	
 	/* If we don't know the type then look it up */
-	if (type == GKR_PARSED_UNKNOWN) {
+	if (!type) {
 		stype = gkr_pk_index_get_string_full (location, unique, "parsed-type");
-		if (stype)
-			type = gkr_pkix_parsed_type_from_string (stype);
+		if (stype && stype[0])
+			type = g_quark_from_string (stype);
 		g_free (stype);
 	}
 	
-	if (type != GKR_PARSED_UNKNOWN) { 
+	if (type) { 
 	 	object = prepare_object (ctx->storage, location, unique, type);
  		g_return_if_fail (object != NULL);
  	
@@ -387,12 +384,12 @@
 
 static void
 parser_parsed_sexp (GkrPkixParser *parser, GQuark location, gkrunique unique,
-	            GkrParsedType type, gcry_sexp_t sexp, ParseContext *ctx)
+	                GQuark type, gcry_sexp_t sexp, ParseContext *ctx)
 {
  	GkrPkObjectStoragePrivate *pv = GKR_PK_OBJECT_STORAGE_GET_PRIVATE (ctx->storage);
  	GkrPkObject *object;
  	
- 	g_return_if_fail (type != GKR_PARSED_UNKNOWN);
+ 	g_return_if_fail (type != 0);
  	
  	object = prepare_object (ctx->storage, location, unique, type);
  	g_return_if_fail (object != NULL);
@@ -413,12 +410,12 @@
 
 static void
 parser_parsed_asn1 (GkrPkixParser *parser, GQuark location, gkrconstunique unique, 
-                    GkrParsedType type, ASN1_TYPE asn1, ParseContext *ctx)
+                    GQuark type, ASN1_TYPE asn1, ParseContext *ctx)
 {
  	GkrPkObjectStoragePrivate *pv = GKR_PK_OBJECT_STORAGE_GET_PRIVATE (ctx->storage);
 	GkrPkObject *object;
 	
- 	g_return_if_fail (type != GKR_PARSED_UNKNOWN);
+ 	g_return_if_fail (type != 0);
  	
 	object = prepare_object (ctx->storage, location, unique, type);
 	g_return_if_fail (object != NULL);
@@ -449,11 +446,11 @@
 index_each_unique (gkrunique unique, gpointer value, gpointer data)
 {
 	GQuark location = GPOINTER_TO_UINT (data);
-	GkrParsedType type = GPOINTER_TO_UINT (value);
+	GQuark type = GPOINTER_TO_UINT (value);
 	
 	/* Stash away the parsed type, in case we need it when prompting for a password */
 	gkr_pk_index_set_string_full (location, unique, "parsed-type", 
-	                              gkr_pkix_parsed_type_to_string (type));
+	                              g_quark_to_string (type));
 }
 
 static gboolean
@@ -461,7 +458,7 @@
 {
  	GkrPkObjectStoragePrivate *pv = GKR_PK_OBJECT_STORAGE_GET_PRIVATE (storage);
  	GkrPkixParser *parser;
- 	GkrParseResult ret;
+ 	GkrPkixResult ret;
  	GkrPkObject *object;
 	ParseContext ctx;
 	GArray *objs;

Modified: trunk/pk/gkr-pk-object.c
==============================================================================
--- trunk/pk/gkr-pk-object.c	(original)
+++ trunk/pk/gkr-pk-object.c	Sun Feb  3 01:28:43 2008
@@ -214,6 +214,16 @@
 	};
 }
 
+static guchar*
+gkr_pk_object_serialize (GkrPkObject *obj, const gchar *password, gsize *n_data)
+{
+	g_return_val_if_fail (GKR_IS_PK_OBJECT (obj), NULL);
+	g_return_val_if_fail (n_data, NULL);
+	
+	*n_data = 0;
+	return NULL;
+}
+
 static void
 gkr_pk_object_get_property (GObject *obj, guint prop_id, GValue *value, 
                              GParamSpec *pspec)
@@ -305,6 +315,7 @@
 	
 	klass->get_attribute = gkr_pk_object_get_attribute_common;
 	klass->set_attribute = gkr_pk_object_set_attribute_common;
+	klass->serialize = gkr_pk_object_serialize;
 
 	g_type_class_add_private (gobject_class, sizeof (GkrPkObjectPrivate));
 	

Modified: trunk/pk/gkr-pk-object.h
==============================================================================
--- trunk/pk/gkr-pk-object.h	(original)
+++ trunk/pk/gkr-pk-object.h	Sun Feb  3 01:28:43 2008
@@ -62,9 +62,23 @@
 struct _GkrPkObjectClass {
 	GObjectClass parent_class;
 
-	/* The attribute getter and setter */
+	/* 
+	 * The attribute getter and setter for PKCS#11 attributes.
+	 * The base class getters and setters provide access to common
+	 * attributes, and derived classes override. 
+	 */
 	CK_RV (*get_attribute) (GkrPkObject *obj, CK_ATTRIBUTE_PTR attr);
 	CK_RV (*set_attribute) (GkrPkObject *obj, CK_ATTRIBUTE_PTR attr); 
+	
+	/* 
+	 * Overridden by derived classes to provide the serialized 
+	 * representation of the object, minus modifiable attributes, and 
+	 * things that go in the index. 
+	 * 
+	 * Objects may choose to use the 'password' to encrypt and/or MAC 
+	 * the data, as long as the representation is later decryptable. 
+	 */
+	guchar* (*serialize) (GkrPkObject *obj, const gchar* password, gsize *n_data);
 };
 
 GType               gkr_pk_object_get_type         (void) G_GNUC_CONST;

Modified: trunk/pk/gkr-pk-privkey.c
==============================================================================
--- trunk/pk/gkr-pk-privkey.c	(original)
+++ trunk/pk/gkr-pk-privkey.c	Sun Feb  3 01:28:43 2008
@@ -40,6 +40,7 @@
 #include "pkcs11/pkcs11g.h"
 
 #include "pkix/gkr-pkix-der.h"
+#include "pkix/gkr-pkix-serialize.h"
 
 #include <glib.h>
 #include <glib-object.h>
@@ -105,7 +106,7 @@
 {
 	gcry_sexp_t s_key = NULL;
 	GkrPkObject *obj;
-	GkrParseResult res;
+	GkrPkixResult res;
 	guchar *data;
 	gsize n_data;
 
@@ -118,7 +119,7 @@
 	data = gkr_pk_index_get_binary (obj, "public-key", &n_data);
 	if (data) {
 		res = gkr_pkix_der_read_public_key (data, n_data, &s_key);
-		if (res == GKR_PARSE_SUCCESS) {
+		if (res == GKR_PKIX_SUCCESS) {
 			key->priv->pubkey = gkr_pk_pubkey_instance (obj->manager, 
 			                                            obj->location, s_key);
 			goto done;
@@ -503,6 +504,20 @@
 	return GKR_PK_OBJECT_CLASS (gkr_pk_privkey_parent_class)->get_attribute (obj, attr);
 }
 
+static guchar*
+gkr_pk_privkey_serialize (GkrPkObject *obj, const gchar *password, gsize *n_data)
+{
+	GkrPkPrivkey *key = GKR_PK_PRIVKEY (obj);
+	
+	if (!load_private_key (key))
+		return NULL;
+		
+	g_return_val_if_fail (key->priv->s_key, NULL);
+	
+	/* Write it out */
+	return gkr_pkix_serialize_private_key_pkcs8 (key->priv->s_key, password, n_data);
+}
+
 static void
 gkr_pk_privkey_dispose (GObject *obj)
 {
@@ -542,6 +557,7 @@
 	
 	parent_class = GKR_PK_OBJECT_CLASS (klass);
 	parent_class->get_attribute = gkr_pk_privkey_get_attribute;
+	parent_class->serialize = gkr_pk_privkey_serialize;
 	
 	gobject_class = (GObjectClass*)klass;
 	gobject_class->get_property = gkr_pk_privkey_get_property;

Modified: trunk/pk/gkr-pk-pubkey.c
==============================================================================
--- trunk/pk/gkr-pk-pubkey.c	(original)
+++ trunk/pk/gkr-pk-pubkey.c	Sun Feb  3 01:28:43 2008
@@ -36,6 +36,7 @@
 #include "common/gkr-unique.h"
 
 #include "pkix/gkr-pkix-der.h"
+#include "pkix/gkr-pkix-serialize.h"
 
 #include <glib.h>
 #include <glib-object.h>
@@ -428,6 +429,20 @@
 	return GKR_PK_OBJECT_CLASS (gkr_pk_pubkey_parent_class)->get_attribute (obj, attr);
 }
 
+static guchar*
+gkr_pk_pubkey_serialize (GkrPkObject *obj, const gchar *password, gsize *n_data)
+{
+	GkrPkPubkey *key = GKR_PK_PUBKEY (obj);
+	
+	if (!load_public_key (key))
+		return NULL;
+		
+	g_return_val_if_fail (key->pub->s_key, NULL);
+	
+	/* Write it to the indexes */
+	return gkr_pkix_serialize_public_key (key->pub->s_key, n_data);
+}
+
 static void
 gkr_pk_pubkey_finalize (GObject *obj)
 {
@@ -453,6 +468,7 @@
 	
 	parent_class = GKR_PK_OBJECT_CLASS (klass);
 	parent_class->get_attribute = gkr_pk_pubkey_get_attribute;
+	parent_class->serialize = gkr_pk_pubkey_serialize;
 	
 	gobject_class = (GObjectClass*)klass;
 	gobject_class->get_property = gkr_pk_pubkey_get_property;

Modified: trunk/pk/tests/unit-test-pk-cert.c
==============================================================================
--- trunk/pk/tests/unit-test-pk-cert.c	(original)
+++ trunk/pk/tests/unit-test-pk-cert.c	Sun Feb  3 01:28:43 2008
@@ -67,7 +67,7 @@
 
 void unit_test_create_certificate (CuTest* cu)
 {
-	GkrParseResult res;
+	GkrPkixResult res;
 	ASN1_TYPE asn1;
 	gcry_sexp_t sexp;
 	gchar *data;
@@ -77,7 +77,7 @@
 	if (!g_file_get_contents ("test-data/certificate-1.crt", &data, &n_data, NULL))
 		g_error ("couldn't read certificate-1.crt");
 	res = gkr_pkix_der_read_certificate ((const guchar*)data, n_data, &asn1);
-	g_assert (res == GKR_PARSE_SUCCESS);
+	g_assert (res == GKR_PKIX_SUCCESS);
 	
 	certificate_1 = gkr_pk_cert_new (manager, 0, asn1);
 	CuAssert (cu, "gkr_pk_cert_new returned bad object", GKR_IS_PK_CERT (certificate_1));
@@ -85,7 +85,7 @@
 	if (!g_file_get_contents ("test-data/privkey-1.key", &data, &n_data, NULL))
 		g_error ("couldn't read privkey-1.key");
 	res = gkr_pkix_der_read_private_key ((const guchar*)data, n_data, &sexp);
-	g_assert (res == GKR_PARSE_SUCCESS);
+	g_assert (res == GKR_PKIX_SUCCESS);
 	
 	privkey_1 = gkr_pk_privkey_new (manager, 0, sexp);
 	g_assert (GKR_IS_PK_PRIVKEY (privkey_1));
@@ -93,7 +93,7 @@
 	if (!g_file_get_contents ("test-data/certificate-2.crt", &data, &n_data, NULL))
 		g_error ("couldn't read certificate-2.crt");
 	res = gkr_pkix_der_read_certificate ((const guchar*)data, n_data, &asn1);
-	g_assert (res == GKR_PARSE_SUCCESS);
+	g_assert (res == GKR_PKIX_SUCCESS);
 	
 	certificate_2 = gkr_pk_cert_new (manager, 0, asn1);
 	CuAssert (cu, "gkr_pk_cert_new returned bad object", GKR_IS_PK_CERT (certificate_2));

Modified: trunk/pk/tests/unit-test-pk-key.c
==============================================================================
--- trunk/pk/tests/unit-test-pk-key.c	(original)
+++ trunk/pk/tests/unit-test-pk-key.c	Sun Feb  3 01:28:43 2008
@@ -71,7 +71,7 @@
 
 void unit_test_create_keys (CuTest* cu)
 {
-	GkrParseResult res;
+	GkrPkixResult res;
 	gcry_sexp_t sexp;
 	gchar *data;
 	gsize n_data;
@@ -79,7 +79,7 @@
 	if (!g_file_get_contents ("test-data/privkey-1.key", &data, &n_data, NULL))
 		g_error ("couldn't read privkey-1.key");
 	res = gkr_pkix_der_read_private_key ((const guchar*)data, n_data, &sexp);
-	g_assert (res == GKR_PARSE_SUCCESS);
+	g_assert (res == GKR_PKIX_SUCCESS);
 	
 	privkey_1 = gkr_pk_privkey_new (manager, 0, sexp);
 	g_assert (GKR_IS_PK_PRIVKEY (privkey_1));
@@ -92,7 +92,7 @@
 	if (!g_file_get_contents ("test-data/privkey-3.key", &data, &n_data, NULL))
 		g_error ("couldn't read privkey-3.key");
 	res = gkr_pkix_der_read_private_key ((const guchar*)data, n_data, &sexp);
-	g_assert (res == GKR_PARSE_SUCCESS);
+	g_assert (res == GKR_PKIX_SUCCESS);
 	
 	privkey_3 = gkr_pk_privkey_new (manager, 0, sexp);
 	g_assert (GKR_IS_PK_PRIVKEY (privkey_3));

Modified: trunk/pk/tests/unit-test-pk-netscape-trust.c
==============================================================================
--- trunk/pk/tests/unit-test-pk-netscape-trust.c	(original)
+++ trunk/pk/tests/unit-test-pk-netscape-trust.c	Sun Feb  3 01:28:43 2008
@@ -67,7 +67,7 @@
 void unit_test_create_trust (CuTest* cu)
 {
 	gkrconstunique keyid;
-	GkrParseResult res;
+	GkrPkixResult res;
 	ASN1_TYPE asn1;
 	gchar *data;
 	gsize n_data;
@@ -75,7 +75,7 @@
 	if (!g_file_get_contents ("test-data/certificate-1.crt", &data, &n_data, NULL))
 		g_error ("couldn't read certificate-1.crt");
 	res = gkr_pkix_der_read_certificate ((const guchar*)data, n_data, &asn1);
-	g_assert (res == GKR_PARSE_SUCCESS);
+	g_assert (res == GKR_PKIX_SUCCESS);
 	certificate_1 = gkr_pk_cert_new (manager, 0, asn1);
 	CuAssert (cu, "gkr_pk_cert_new returned bad object", GKR_IS_PK_CERT (certificate_1));
 
@@ -91,7 +91,7 @@
 	if (!g_file_get_contents ("test-data/certificate-2.crt", &data, &n_data, NULL))
 		g_error ("couldn't read certificate-2.crt");
 	res = gkr_pkix_der_read_certificate ((const guchar*)data, n_data, &asn1);
-	g_assert (res == GKR_PARSE_SUCCESS);
+	g_assert (res == GKR_PKIX_SUCCESS);
 	certificate_2 = gkr_pk_cert_new (manager, 0, asn1);
 	CuAssert (cu, "gkr_pk_cert_new returned bad object", GKR_IS_PK_CERT (certificate_2));
 

Modified: trunk/pkix/Makefile.am
==============================================================================
--- trunk/pkix/Makefile.am	(original)
+++ trunk/pkix/Makefile.am	Sun Feb  3 01:28:43 2008
@@ -23,6 +23,8 @@
 	gkr-pkix-openssl.c gkr-pkix-openssl.h \
 	gkr-pkix-parser.c gkr-pkix-parser.h \
 	gkr-pkix-pem.c gkr-pkix-pem.h \
+	gkr-pkix-serialize.c gkr-pkix-serialize.h \
+	gkr-pkix-types.h \
 	$(BUILT_SOURCES)
 
 gkr-pkix-marshal.h: gkr-pkix-marshal.list $(GLIB_GENMARSHAL)

Modified: trunk/pkix/gkr-pkix-asn1.c
==============================================================================
--- trunk/pkix/gkr-pkix-asn1.c	(original)
+++ trunk/pkix/gkr-pkix-asn1.c	Sun Feb  3 01:28:43 2008
@@ -262,6 +262,20 @@
 }
 
 gboolean
+gkr_pkix_asn1_write_value (ASN1_TYPE asn, const gchar *part, 
+		                   const guchar* value, gsize len)
+{
+	int res;
+
+	g_return_val_if_fail (asn, FALSE);
+	g_return_val_if_fail (part, FALSE);
+	g_return_val_if_fail (!len || value, FALSE);
+	
+	res = asn1_write_value (asn, part, (const void*)value, (int)len);
+	return res == ASN1_SUCCESS;
+}
+
+gboolean
 gkr_pkix_asn1_read_boolean (ASN1_TYPE asn, const gchar *part, gboolean *val)
 {
 	gchar buffer[32];
@@ -327,7 +341,7 @@
 }
 
 GQuark
-gkr_pkix_asn1_read_quark (ASN1_TYPE asn, const gchar *part)
+gkr_pkix_asn1_read_oid (ASN1_TYPE asn, const gchar *part)
 {
 	GQuark quark;
 	guchar *buf;
@@ -344,6 +358,20 @@
 }
 
 gboolean
+gkr_pkix_asn1_write_oid (ASN1_TYPE asn, const gchar *part, GQuark val)
+{
+	const gchar* oid;
+	
+	g_return_val_if_fail (val, FALSE);
+	
+	oid = g_quark_to_string (val);
+	g_return_val_if_fail (oid, FALSE);
+	
+	return gkr_pkix_asn1_write_value (asn, part, (const guchar*)oid, 
+			                          1 /* any non-null value for OID */);
+}
+
+gboolean
 gkr_pkix_asn1_read_mpi (ASN1_TYPE asn, const gchar *part, gcry_mpi_t *mpi)
 {
   	gcry_error_t gcry;
@@ -354,7 +382,7 @@
 	if (!buf)
 		return FALSE;
 	
-	gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_USG, buf, sz, &sz);
+	gcry = gcry_mpi_scan (mpi, GCRYMPI_FMT_STD, buf, sz, &sz);
 	gkr_secure_free (buf);
 
 	if (gcry != 0)
@@ -376,13 +404,13 @@
 	g_assert (mpi);
 	
 	/* Get the size */
-	gcry = gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &len, mpi);
+	gcry = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &len, mpi);
 	g_return_val_if_fail (gcry == 0, FALSE);
 	g_return_val_if_fail (len > 0, FALSE); 
 
 	buf = gkr_secure_alloc (len);
 	
-	gcry = gcry_mpi_print (GCRYMPI_FMT_USG, buf, len, &len, mpi);	
+	gcry = gcry_mpi_print (GCRYMPI_FMT_STD, buf, len, &len, mpi);	
 	g_return_val_if_fail (gcry == 0, FALSE);
 	
 	res = asn1_write_value (asn, part, buf, len);

Modified: trunk/pkix/gkr-pkix-asn1.h
==============================================================================
--- trunk/pkix/gkr-pkix-asn1.h	(original)
+++ trunk/pkix/gkr-pkix-asn1.h	Sun Feb  3 01:28:43 2008
@@ -43,7 +43,12 @@
 guchar*            gkr_pkix_asn1_read_value                    (ASN1_TYPE asn, const gchar *part, 
                                                                 gsize *len, GkrBufferAllocator alloc);
 
-GQuark             gkr_pkix_asn1_read_quark                    (ASN1_TYPE asn, const gchar *part);
+gboolean           gkr_pkix_asn1_write_value                   (ASN1_TYPE asn, const gchar *part, 
+		                                                        const guchar* value, gsize len); 
+
+GQuark             gkr_pkix_asn1_read_oid                      (ASN1_TYPE asn, const gchar *part);
+
+gboolean           gkr_pkix_asn1_write_oid                     (ASN1_TYPE asn, const gchar *part, GQuark val);
 
 gboolean           gkr_pkix_asn1_read_boolean                  (ASN1_TYPE asn, const gchar *part, gboolean *val);
 

Modified: trunk/pkix/gkr-pkix-der.c
==============================================================================
--- trunk/pkix/gkr-pkix-der.c	(original)
+++ trunk/pkix/gkr-pkix-der.c	Sun Feb  3 01:28:43 2008
@@ -113,10 +113,10 @@
 	"    (n %m)"     \
 	"    (e %m)))"
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_public_key_rsa (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	gcry_mpi_t n, e;
 	int res;
@@ -127,7 +127,7 @@
 	if (!asn)
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
     
 	if (!gkr_pkix_asn1_read_mpi (asn, "modulus", &n) || 
 	    !gkr_pkix_asn1_read_mpi (asn, "publicExponent", &e))
@@ -138,7 +138,7 @@
 		goto done;
 
 	g_assert (*s_key);
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 
 done:
 	if (asn)
@@ -146,7 +146,7 @@
 	gcry_mpi_release (n);
 	gcry_mpi_release (e);
 	
-	if (ret == GKR_PARSE_FAILURE)
+	if (ret == GKR_PKIX_FAILURE)
 		g_message ("invalid RSA public key");
 		
 	return ret;
@@ -162,12 +162,13 @@
 	"    (q %m)"     \
 	"    (u %m)))"
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_private_key_rsa (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	gcry_mpi_t n, e, d, p, q, u;
 	gcry_mpi_t tmp;
+	guint version;
 	int res;
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 
@@ -177,7 +178,17 @@
 	if (!asn)
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
+	
+	if (!gkr_pkix_asn1_read_uint (asn, "version", &version))
+		goto done;
+	
+	/* We only support simple version */
+	if (version != 0) {
+		ret = GKR_PKIX_UNRECOGNIZED;
+		g_message ("unsupported version of RSA key: %u", version);
+		goto done;
+	}
     
 	if (!gkr_pkix_asn1_read_mpi (asn, "modulus", &n) || 
 	    !gkr_pkix_asn1_read_mpi (asn, "publicExponent", &e) ||
@@ -203,7 +214,7 @@
 		goto done;
 
 	g_assert (*s_key);
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 
 done:
 	if (asn)
@@ -215,7 +226,7 @@
 	gcry_mpi_release (q);
 	gcry_mpi_release (u);
 	
-	if (ret == GKR_PARSE_FAILURE)
+	if (ret == GKR_PKIX_FAILURE)
 		g_message ("invalid RSA key");
 		
 	return ret;
@@ -229,10 +240,10 @@
 	"    (g %m)"     \
 	"    (y %m)))"
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_public_key_dsa (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	gcry_mpi_t p, q, g, y;
 	int res;
@@ -243,7 +254,7 @@
 	if (!asn)
 		goto done;
 	
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
     
 	if (!gkr_pkix_asn1_read_mpi (asn, "p", &p) || 
 	    !gkr_pkix_asn1_read_mpi (asn, "q", &q) ||
@@ -256,7 +267,7 @@
 		goto done;
 		
 	g_assert (*s_key);
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
 	if (asn)
@@ -266,19 +277,19 @@
 	gcry_mpi_release (g);
 	gcry_mpi_release (y);
 	
-	if (ret == GKR_PARSE_FAILURE) 
+	if (ret == GKR_PKIX_FAILURE) 
 		g_message ("invalid public DSA key");
 		
 	return ret;	
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_public_key_dsa_parts (const guchar *keydata, gsize n_keydata,
                                         const guchar *params, gsize n_params,
                                         gcry_sexp_t *s_key)
 {
 	gcry_mpi_t p, q, g, y;
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	ASN1_TYPE asn_params = ASN1_TYPE_EMPTY;
 	ASN1_TYPE asn_key = ASN1_TYPE_EMPTY;
 	int res;
@@ -290,7 +301,7 @@
 	if (!asn_params || !asn_key)
 		goto done;
 	
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
     
 	if (!gkr_pkix_asn1_read_mpi (asn_params, "p", &p) || 
 	    !gkr_pkix_asn1_read_mpi (asn_params, "q", &q) ||
@@ -305,7 +316,7 @@
 		goto done;
 		
 	g_assert (*s_key);
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
 	if (asn_key)
@@ -317,7 +328,7 @@
 	gcry_mpi_release (g);
 	gcry_mpi_release (y);
 	
-	if (ret == GKR_PARSE_FAILURE) 
+	if (ret == GKR_PKIX_FAILURE) 
 		g_message ("invalid DSA key");
 		
 	return ret;	
@@ -333,11 +344,11 @@
 	"    (y %m)"     \
 	"    (x %m)))"
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_private_key_dsa (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
 {
 	gcry_mpi_t p, q, g, y, x;
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	int res;
 	ASN1_TYPE asn;
 
@@ -347,7 +358,7 @@
 	if (!asn)
 		goto done;
 	
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
     
 	if (!gkr_pkix_asn1_read_mpi (asn, "p", &p) || 
 	    !gkr_pkix_asn1_read_mpi (asn, "q", &q) ||
@@ -361,7 +372,7 @@
 		goto done;
 		
 	g_assert (*s_key);
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 
 done:
 	if (asn)
@@ -372,19 +383,19 @@
 	gcry_mpi_release (y);
 	gcry_mpi_release (x);
 	
-	if (ret == GKR_PARSE_FAILURE) 
+	if (ret == GKR_PKIX_FAILURE) 
 		g_message ("invalid DSA key");
 		
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_private_key_dsa_parts (const guchar *keydata, gsize n_keydata,
                                          const guchar *params, gsize n_params, 
                                          gcry_sexp_t *s_key)
 {
 	gcry_mpi_t p, q, g, y, x;
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	int res;
 	ASN1_TYPE asn_params = ASN1_TYPE_EMPTY;
 	ASN1_TYPE asn_key = ASN1_TYPE_EMPTY;
@@ -396,7 +407,7 @@
 	if (!asn_params || !asn_key)
 		goto done;
 	
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
     
 	if (!gkr_pkix_asn1_read_mpi (asn_params, "p", &p) || 
 	    !gkr_pkix_asn1_read_mpi (asn_params, "q", &q) ||
@@ -415,7 +426,7 @@
 		goto done;
 		
 	g_assert (*s_key);
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
 	if (asn_key)
@@ -428,28 +439,28 @@
 	gcry_mpi_release (y);
 	gcry_mpi_release (x);
 	
-	if (ret == GKR_PARSE_FAILURE) 
+	if (ret == GKR_PKIX_FAILURE) 
 		g_message ("invalid DSA key");
 		
 	return ret;	
 }
 
-GkrParseResult  
+GkrPkixResult  
 gkr_pkix_der_read_public_key (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
 {
-	GkrParseResult res;
+	GkrPkixResult res;
 	
 	res = gkr_pkix_der_read_public_key_rsa (data, n_data, s_key);
-	if (res == GKR_PARSE_UNRECOGNIZED)
+	if (res == GKR_PKIX_UNRECOGNIZED)
 		res = gkr_pkix_der_read_public_key_dsa (data, n_data, s_key);
 		
 	return res;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_public_key_info (const guchar* data, gsize n_data, gcry_sexp_t* s_key)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	GQuark oid;
 	ASN1_TYPE asn;
 	gsize n_key, n_params;
@@ -462,10 +473,10 @@
 	if (!asn)
 		goto done;
 	
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
     
 	/* Figure out the algorithm */
-	oid = gkr_pkix_asn1_read_quark (asn, "algorithm.algorithm");
+	oid = gkr_pkix_asn1_read_oid (asn, "algorithm.algorithm");
 	if (!oid)
 		goto done;
 		
@@ -497,19 +508,19 @@
 	
 	g_free (key);
 		
-	if (ret == GKR_PARSE_FAILURE)
+	if (ret == GKR_PKIX_FAILURE)
 		g_message ("invalid subject public-key info");
 		
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_private_key (const guchar *data, gsize n_data, gcry_sexp_t *s_key)
 {
-	GkrParseResult res;
+	GkrPkixResult res;
 	
 	res = gkr_pkix_der_read_private_key_rsa (data, n_data, s_key);
-	if (res == GKR_PARSE_UNRECOGNIZED)
+	if (res == GKR_PKIX_UNRECOGNIZED)
 		res = gkr_pkix_der_read_private_key_dsa (data, n_data, s_key);
 		
 	return res;
@@ -549,6 +560,73 @@
 }
 
 guchar*
+gkr_pkix_der_write_private_key_rsa (gcry_sexp_t s_key, gsize *n_key)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_mpi_t n, e, d, p, q, u, e1, e2, tmp;
+	guchar *result = NULL;
+	int res;
+
+	n = e = d = p = q = u = e1 = e2 = tmp = NULL;
+
+	res = asn1_create_element (gkr_pkix_asn1_get_pk_asn1type (), 
+	                           "PK.RSAPrivateKey", &asn);
+	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+
+	if (!gkr_crypto_sexp_extract_mpi (s_key, &n, "rsa", "n", NULL) || 
+	    !gkr_crypto_sexp_extract_mpi (s_key, &e, "rsa", "e", NULL) ||
+	    !gkr_crypto_sexp_extract_mpi (s_key, &d, "rsa", "d", NULL) ||
+	    !gkr_crypto_sexp_extract_mpi (s_key, &p, "rsa", "p", NULL) ||
+	    !gkr_crypto_sexp_extract_mpi (s_key, &q, "rsa", "q", NULL) ||
+	    !gkr_crypto_sexp_extract_mpi (s_key, &u, "rsa", "u", NULL))
+		goto done;
+	
+	if (!gkr_pkix_asn1_write_mpi (asn, "modulus", n) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "publicExponent", e) || 
+	    !gkr_pkix_asn1_write_mpi (asn, "privateExponent", d) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "prime1", p) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "prime2", q) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "coefficient", u))
+		goto done;
+
+	/* Calculate e1 and e2 */
+	tmp = gcry_mpi_snew (1024);
+	gcry_mpi_sub_ui (tmp, p, 1);
+	e1 = gcry_mpi_snew (1024);
+	gcry_mpi_mod (e1, d, tmp);
+	gcry_mpi_sub_ui (tmp, q, 1);
+	e2 = gcry_mpi_snew (1024);
+	gcry_mpi_mod (e2, d, tmp);
+	
+	/* Write out calculated */
+	if (!gkr_pkix_asn1_write_mpi (asn, "exponent1", e1) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "exponent2", e2))
+		goto done;
+
+	/* Write out the version */
+	if (!gkr_pkix_asn1_write_uint (asn, "version", 0))
+		goto done;
+
+	result = gkr_pkix_asn1_encode (asn, "", n_key, NULL);
+	
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+	gcry_mpi_release (n);
+	gcry_mpi_release (e);
+	gcry_mpi_release (d);
+	gcry_mpi_release (p);
+	gcry_mpi_release (q);
+	gcry_mpi_release (u);
+	
+	gcry_mpi_release (tmp);
+	gcry_mpi_release (e1);
+	gcry_mpi_release (e2);
+	
+	return result;
+}
+
+guchar*
 gkr_pkix_der_write_public_key_dsa (gcry_sexp_t s_key, gsize *len)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
@@ -591,6 +669,117 @@
 }
 
 guchar*
+gkr_pkix_der_write_private_key_dsa_part (gcry_sexp_t skey, gsize *n_key)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_mpi_t x;
+	guchar *result = NULL;
+	int res;
+
+	x = NULL;
+
+	res = asn1_create_element (gkr_pkix_asn1_get_pk_asn1type (), 
+	                           "PK.DSAPrivatePart", &asn);
+	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+
+	if (!gkr_crypto_sexp_extract_mpi (skey, &x, "dsa", "x", NULL))
+	    	goto done;
+	
+	if (!gkr_pkix_asn1_write_mpi (asn, "", x))
+	    	goto done;
+
+	result = gkr_pkix_asn1_encode (asn, "", n_key, NULL);
+	
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+	gcry_mpi_release (x);
+	
+	return result;		
+}
+
+guchar*
+gkr_pkix_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_mpi_t p, q, g;
+	guchar *result = NULL;
+	int res;
+
+	p = q = g = NULL;
+
+	res = asn1_create_element (gkr_pkix_asn1_get_pk_asn1type (), 
+	                           "PK.DSAParameters", &asn);
+	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+
+	if (!gkr_crypto_sexp_extract_mpi (skey, &p, "dsa", "p", NULL) || 
+	    !gkr_crypto_sexp_extract_mpi (skey, &q, "dsa", "q", NULL) ||
+	    !gkr_crypto_sexp_extract_mpi (skey, &g, "dsa", "g", NULL))
+	    	goto done;
+	
+	if (!gkr_pkix_asn1_write_mpi (asn, "p", p) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "q", q) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "g", g))
+	    	goto done;
+
+	result = gkr_pkix_asn1_encode (asn, "", n_params, NULL);
+	
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+	gcry_mpi_release (p);
+	gcry_mpi_release (q);
+	gcry_mpi_release (g);
+	
+	return result;
+}
+
+guchar*
+gkr_pkix_der_write_private_key_dsa (gcry_sexp_t s_key, gsize *len)
+{
+	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
+	gcry_mpi_t p, q, g, y, x;
+	guchar *result = NULL;
+	int res;
+
+	p = q = g = y = x = NULL;
+
+	res = asn1_create_element (gkr_pkix_asn1_get_pk_asn1type (), 
+	                           "PK.DSAPrivateKey", &asn);
+	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+
+	if (!gkr_crypto_sexp_extract_mpi (s_key, &p, "dsa", "p", NULL) || 
+	    !gkr_crypto_sexp_extract_mpi (s_key, &q, "dsa", "q", NULL) ||
+	    !gkr_crypto_sexp_extract_mpi (s_key, &g, "dsa", "g", NULL) ||
+	    !gkr_crypto_sexp_extract_mpi (s_key, &y, "dsa", "y", NULL) ||
+	    !gkr_crypto_sexp_extract_mpi (s_key, &x, "dsa", "x", NULL))
+	    	goto done;
+	
+	if (!gkr_pkix_asn1_write_mpi (asn, "p", p) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "q", q) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "g", g) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "Y", y) ||
+	    !gkr_pkix_asn1_write_mpi (asn, "priv", x))
+	    	goto done;
+
+	if (!gkr_pkix_asn1_write_uint (asn, "version", 0))
+		goto done; 
+		
+	result = gkr_pkix_asn1_encode (asn, "", len, NULL);
+	
+done:
+	if (asn)
+		asn1_delete_structure (&asn);
+	gcry_mpi_release (p);
+	gcry_mpi_release (q);
+	gcry_mpi_release (g);
+	gcry_mpi_release (y);
+	gcry_mpi_release (x);
+	
+	return result;
+}
+
+guchar*
 gkr_pkix_der_write_public_key (gcry_sexp_t s_key, gsize *len)
 {
 	gboolean is_priv;
@@ -613,32 +802,55 @@
 	}
 }
 
+guchar*
+gkr_pkix_der_write_private_key (gcry_sexp_t s_key, gsize *len)
+{
+	gboolean is_priv;
+	int algorithm;
+	
+	g_return_val_if_fail (s_key != NULL, NULL);
+	
+	if (!gkr_crypto_skey_parse (s_key, &algorithm, &is_priv, NULL))
+		g_return_val_if_reached (NULL);
+	
+	g_return_val_if_fail (is_priv, NULL);
+		
+	switch (algorithm) {
+	case GCRY_PK_RSA:
+		return gkr_pkix_der_write_private_key_rsa (s_key, len);
+	case GCRY_PK_DSA:
+		return gkr_pkix_der_write_private_key_dsa (s_key, len);
+	default:
+		g_return_val_if_reached (NULL);
+	}
+}
+
 /* -----------------------------------------------------------------------------
  * CERTIFICATES
  */
  
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_certificate (const guchar *data, gsize n_data, ASN1_TYPE *asn1)
 {
 	*asn1 = gkr_pkix_asn1_decode ("PKIX1.Certificate", data, n_data);
 	if (!*asn1)
-		return GKR_PARSE_UNRECOGNIZED;
+		return GKR_PKIX_UNRECOGNIZED;
 	
-	return GKR_PARSE_SUCCESS;
+	return GKR_PKIX_SUCCESS;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_basic_constraints (const guchar *data, gsize n_data, 
                                      gboolean *is_ca, guint *path_len)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	ASN1_TYPE asn;
 
 	asn = gkr_pkix_asn1_decode ("PKIX1.BasicConstraints", data, n_data);
 	if (!asn)
 		goto done;
 	
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
     
     	if (path_len) {
     		if (!gkr_pkix_asn1_read_uint (asn, "pathLenConstraint", path_len))
@@ -650,22 +862,22 @@
     			*is_ca = FALSE;
     	}
     	
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 
 done:
 	if (asn)
 		asn1_delete_structure (&asn);
 	
-	if (ret == GKR_PARSE_FAILURE) 
+	if (ret == GKR_PKIX_FAILURE) 
 		g_message ("invalid basic constraints");
 		
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_key_usage (const guchar *data, gsize n_data, guint *key_usage)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	ASN1_TYPE asn;
 	guchar buf[4];
 	int res, len;
@@ -674,7 +886,7 @@
 	if (!asn)
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 
 	memset (buf, 0, sizeof (buf));
 	len = sizeof (buf);
@@ -683,7 +895,7 @@
   		goto done;
 
 	*key_usage = buf[0] | (buf[1] << 8);
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
 	if (asn)
@@ -691,10 +903,10 @@
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_der_read_enhanced_usage (const guchar *data, gsize n_data, GQuark **usage_oids)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	ASN1_TYPE asn;
 	gchar *part;
 	GArray *array;
@@ -705,12 +917,12 @@
 	if (!asn)
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 	
 	array = g_array_new (TRUE, TRUE, sizeof (GQuark));
 	for (i = 0; TRUE; ++i) {
 		part = g_strdup_printf ("?%d", i + 1);
-		oid = gkr_pkix_asn1_read_quark (asn, part);
+		oid = gkr_pkix_asn1_read_oid (asn, part);
 		g_free (part);
 		
 		if (!oid) 
@@ -720,7 +932,7 @@
 	}
 	
 	*usage_oids = (GQuark*)g_array_free (array, FALSE);
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
 	if (asn)
@@ -728,85 +940,93 @@
 	return ret;
 }
 
+guchar*
+gkr_pkix_der_write_certificate (ASN1_TYPE asn1, gsize *n_data)
+{
+	g_return_val_if_fail (asn1, NULL);
+	g_return_val_if_fail (n_data, NULL);
+	
+	return gkr_pkix_asn1_encode (asn1, "", n_data, NULL);
+}
+
 /* -----------------------------------------------------------------------------
  * CIPHER/KEY DESCRIPTIONS 
  */
  
-GkrParseResult
-gkr_pkix_der_read_cipher (GkrPkixParser *parser, GQuark oid_scheme, const gchar *password, 
+GkrPkixResult
+gkr_pkix_der_read_cipher (GQuark oid_scheme, const gchar *password, 
                           const guchar *data, gsize n_data, gcry_cipher_hd_t *cih)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	
-	g_return_val_if_fail (GKR_IS_PKIX_PARSER (parser), GKR_PARSE_FAILURE);
-	g_return_val_if_fail (oid_scheme != 0, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (cih != NULL, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (data != NULL && n_data != 0, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (password != NULL, GKR_PARSE_FAILURE);
+	g_return_val_if_fail (oid_scheme != 0, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (cih != NULL, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (data != NULL && n_data != 0, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (password != NULL, GKR_PKIX_FAILURE);
 	
 	init_quarks ();
 	
 	/* PKCS#5 PBE */
 	if (oid_scheme == OID_PBE_MD2_DES_CBC)
-		ret = gkr_pkix_der_read_cipher_pkcs5_pbe (parser, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+		ret = gkr_pkix_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
 		                                          GCRY_MD_MD2, password, data, n_data, cih);
 
 	else if (oid_scheme == OID_PBE_MD2_RC2_CBC)
 		/* RC2-64 has no implementation in libgcrypt */
-		ret = GKR_PARSE_UNRECOGNIZED;
+		ret = GKR_PKIX_UNRECOGNIZED;
 	else if (oid_scheme == OID_PBE_MD5_DES_CBC)
-		ret = gkr_pkix_der_read_cipher_pkcs5_pbe (parser, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+		ret = gkr_pkix_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
 		                                          GCRY_MD_MD5, password, data, n_data, cih);
 	else if (oid_scheme == OID_PBE_MD5_RC2_CBC)
 		/* RC2-64 has no implementation in libgcrypt */
-		ret = GKR_PARSE_UNRECOGNIZED;
+		ret = GKR_PKIX_UNRECOGNIZED;
 	else if (oid_scheme == OID_PBE_SHA1_DES_CBC)
-		ret = gkr_pkix_der_read_cipher_pkcs5_pbe (parser, GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
+		ret = gkr_pkix_der_read_cipher_pkcs5_pbe (GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC,
 		                                          GCRY_MD_SHA1, password, data, n_data, cih);
 	else if (oid_scheme == OID_PBE_SHA1_RC2_CBC)
 		/* RC2-64 has no implementation in libgcrypt */
-		ret = GKR_PARSE_UNRECOGNIZED;
+		ret = GKR_PKIX_UNRECOGNIZED;
 
 	
 	/* PKCS#5 PBES2 */
 	else if (oid_scheme == OID_PBES2)
-		ret = gkr_pkix_der_read_cipher_pkcs5_pbes2 (parser, password, data, n_data, cih);
+		ret = gkr_pkix_der_read_cipher_pkcs5_pbes2 (password, data, n_data, cih);
 
 		
 	/* PKCS#12 PBE */
 	else if (oid_scheme == OID_PKCS12_PBE_ARCFOUR_SHA1)
-		ret = gkr_pkix_der_read_cipher_pkcs12_pbe (parser, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 
-	                                                   password, data, n_data, cih);
+		ret = gkr_pkix_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 
+                                                   password, data, n_data, cih);
 	else if (oid_scheme == OID_PKCS12_PBE_RC4_40_SHA1)
 		/* RC4-40 has no implementation in libgcrypt */;
 
 	else if (oid_scheme == OID_PKCS12_PBE_3DES_SHA1)
-		ret = gkr_pkix_der_read_cipher_pkcs12_pbe (parser, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 
-	                                                   password, data, n_data, cih);
+		ret = gkr_pkix_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 
+                                                   password, data, n_data, cih);
 	else if (oid_scheme == OID_PKCS12_PBE_2DES_SHA1) 
 		/* 2DES has no implementation in libgcrypt */;
 		
 	else if (oid_scheme == OID_PKCS12_PBE_RC2_128_SHA1)
-		ret = gkr_pkix_der_read_cipher_pkcs12_pbe (parser, GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC, 
-	                                                   password, data, n_data, cih);
+		ret = gkr_pkix_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_128, GCRY_CIPHER_MODE_CBC, 
+                                                   password, data, n_data, cih);
 
 	else if (oid_scheme == OID_PKCS12_PBE_RC2_40_SHA1)
-		ret = gkr_pkix_der_read_cipher_pkcs12_pbe (parser, GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC, 
-	                                                   password, data, n_data, cih);
+		ret = gkr_pkix_der_read_cipher_pkcs12_pbe (GCRY_CIPHER_RFC2268_40, GCRY_CIPHER_MODE_CBC, 
+                                                   password, data, n_data, cih);
 
-	if (ret == GKR_PARSE_UNRECOGNIZED)
+	if (ret == GKR_PKIX_UNRECOGNIZED)
     		g_message ("unsupported or unrecognized cipher oid: %s", g_quark_to_string (oid_scheme));
     	return ret;
 }
 
-GkrParseResult
-gkr_pkix_der_read_cipher_pkcs5_pbe (GkrPkixParser *parser, int cipher_algo, int cipher_mode, 
+GkrPkixResult
+gkr_pkix_der_read_cipher_pkcs5_pbe (int cipher_algo, int cipher_mode, 
                                     int hash_algo, const gchar *password, const guchar *data, 
                                     gsize n_data, gcry_cipher_hd_t *cih)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	gcry_error_t gcry;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	const guchar *salt;
 	gsize n_salt;
 	gsize n_block, n_key;
@@ -814,14 +1034,13 @@
 	guchar *key = NULL;
 	guchar *iv = NULL;
 
-	g_return_val_if_fail (GKR_IS_PKIX_PARSER (parser), GKR_PARSE_FAILURE);
-	g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (cih != NULL, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (data != NULL && n_data != 0, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (password != NULL, GKR_PARSE_FAILURE);
+	g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (cih != NULL, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (data != NULL && n_data != 0, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (password != NULL, GKR_PKIX_FAILURE);
 
 	*cih = NULL;	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	/* Check if we can use this algorithm */
 	if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0 ||
@@ -832,7 +1051,7 @@
 	if (!asn) 
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 		
 	salt = gkr_pkix_asn1_read_content (asn, data, n_data, "salt", &n_salt);
 	if (!salt)
@@ -841,7 +1060,7 @@
 		iterations = 1;
 		
 	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	g_return_val_if_fail (n_key > 0, GKR_PARSE_FAILURE);
+	g_return_val_if_fail (n_key > 0, GKR_PKIX_FAILURE);
 	n_block = gcry_cipher_get_algo_blklen (cipher_algo);
 		
 	if (!gkr_crypto_generate_symkey_pbe (cipher_algo, hash_algo, password, salt,
@@ -858,7 +1077,7 @@
 		gcry_cipher_setiv (*cih, iv, n_block);
 	gcry_cipher_setkey (*cih, key, n_key);
 	
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 
 done:
 	gkr_secure_free (iv);
@@ -871,8 +1090,7 @@
 }
 
 static gboolean
-setup_pkcs5_rc2_params (GkrPkixParser *parser, const guchar *data, guchar n_data,
-                        gcry_cipher_hd_t cih)
+setup_pkcs5_rc2_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	gcry_error_t gcry;
@@ -884,30 +1102,29 @@
 
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-5-rc2-CBC-params", data, n_data);
 	if (!asn) 
-		return GKR_PARSE_UNRECOGNIZED;
+		return GKR_PKIX_UNRECOGNIZED;
 		
 	if (!gkr_pkix_asn1_read_uint (asn, "rc2ParameterVersion", &version))
-		return GKR_PARSE_FAILURE;
+		return GKR_PKIX_FAILURE;
 	
 	iv = gkr_pkix_asn1_read_content (asn, data, n_data, "iv", &n_iv);
 	asn1_delete_structure (&asn);
 
 	if (!iv)
-		return GKR_PARSE_FAILURE;
+		return GKR_PKIX_FAILURE;
 		
 	gcry = gcry_cipher_setiv (cih, iv, n_iv);
 			
 	if (gcry != 0) {
 		g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
-		return GKR_PARSE_FAILURE;
+		return GKR_PKIX_FAILURE;
 	}
 	
-	return GKR_PARSE_SUCCESS;
+	return GKR_PKIX_SUCCESS;
 }
 
 static gboolean
-setup_pkcs5_des_params (GkrPkixParser *parser, const guchar *data, guchar n_data,
-                        gcry_cipher_hd_t cih)
+setup_pkcs5_des_params (const guchar *data, guchar n_data, gcry_cipher_hd_t cih)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	gcry_error_t gcry;
@@ -920,30 +1137,30 @@
 	if (!asn)
 		asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-5-des-CBC-params", data, n_data);
 	if (!asn) 
-		return GKR_PARSE_UNRECOGNIZED;
+		return GKR_PKIX_UNRECOGNIZED;
 	
 	iv = gkr_pkix_asn1_read_content (asn, data, n_data, "", &n_iv);
 	asn1_delete_structure (&asn);
 
 	if (!iv)
-		return GKR_PARSE_FAILURE;
+		return GKR_PKIX_FAILURE;
 		
 	gcry = gcry_cipher_setiv (cih, iv, n_iv);
 			
 	if (gcry != 0) {
 		g_message ("couldn't set %lu byte iv on cipher", (gulong)n_iv);
-		return GKR_PARSE_FAILURE;
+		return GKR_PKIX_FAILURE;
 	}
 	
-	return GKR_PARSE_SUCCESS;
+	return GKR_PKIX_SUCCESS;
 }
 
-static GkrParseResult
-setup_pkcs5_pbkdf2_params (GkrPkixParser *parser, const gchar *password, const guchar *data, 
+static GkrPkixResult
+setup_pkcs5_pbkdf2_params (const gchar *password, const guchar *data, 
                            gsize n_data, int cipher_algo, gcry_cipher_hd_t cih)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	gcry_error_t gcry;
 	guchar *key = NULL; 
 	const guchar *salt;
@@ -954,13 +1171,13 @@
 	g_assert (cipher_algo);
 	g_assert (data);
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-5-PBKDF2-params", data, n_data);
 	if (!asn)
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 		
 	if (!gkr_pkix_asn1_read_uint (asn, "iterationCount", &iterations))
 		iterations = 1;
@@ -973,7 +1190,7 @@
 		goto done;
 
 	n_key = gcry_cipher_get_algo_keylen (cipher_algo);
-	g_return_val_if_fail (n_key > 0, GKR_PARSE_FAILURE);
+	g_return_val_if_fail (n_key > 0, GKR_PKIX_FAILURE);
 	
 	gcry = gcry_cipher_setkey (cih, key, n_key);
 	if (gcry != 0) {
@@ -981,7 +1198,7 @@
 		goto done;
 	}
 	
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	                                         
 done:
 	gkr_secure_free (key);
@@ -990,36 +1207,35 @@
 	return ret;
 }
 
-GkrParseResult
-gkr_pkix_der_read_cipher_pkcs5_pbes2 (GkrPkixParser *parser, const gchar *password, const guchar *data, 
+GkrPkixResult
+gkr_pkix_der_read_cipher_pkcs5_pbes2 (const gchar *password, const guchar *data, 
                                       gsize n_data, gcry_cipher_hd_t *cih)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GkrParseResult r, ret;
+	GkrPkixResult r, ret;
 	GQuark key_deriv_algo, enc_oid;
 	gcry_error_t gcry;
 	int algo, mode;
 	int beg, end, res;
 
-	g_return_val_if_fail (GKR_IS_PKIX_PARSER (parser), GKR_PARSE_FAILURE);
-	g_return_val_if_fail (cih != NULL, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (data != NULL && n_data != 0, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (password != NULL, GKR_PARSE_FAILURE);
+	g_return_val_if_fail (cih != NULL, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (data != NULL && n_data != 0, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (password != NULL, GKR_PKIX_FAILURE);
 	
 	init_quarks ();
 	
 	*cih = NULL;
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-5-PBES2-params", data, n_data);
 	if (!asn)
 		goto done;
 		
-	res = GKR_PARSE_FAILURE;
+	res = GKR_PKIX_FAILURE;
 	algo = mode = 0;
 	
 	/* Read in all the encryption type */
-	enc_oid = gkr_pkix_asn1_read_quark (asn, "encryptionScheme.algorithm");
+	enc_oid = gkr_pkix_asn1_read_oid (asn, "encryptionScheme.algorithm");
 	if (!enc_oid)
 		goto done;	
 	if (enc_oid == OID_DES_EDE3_CBC)
@@ -1033,7 +1249,7 @@
 	
 	/* Unsupported? */
 	if (algo == 0 || gcry_cipher_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0) {
-		ret = GKR_PARSE_UNRECOGNIZED;
+		ret = GKR_PKIX_UNRECOGNIZED;
 		goto done;
 	}
 
@@ -1052,30 +1268,30 @@
 	switch (algo) {
 	case GCRY_CIPHER_3DES:
 	case GCRY_CIPHER_DES:
-		r = setup_pkcs5_des_params (parser, data + beg, end - beg + 1, *cih);
+		r = setup_pkcs5_des_params (data + beg, end - beg + 1, *cih);
 		break;
 	case GCRY_CIPHER_RFC2268_128:
-		r = setup_pkcs5_rc2_params (parser, data + beg, end - beg + 1, *cih);
+		r = setup_pkcs5_rc2_params (data + beg, end - beg + 1, *cih);
 		break;
 	default:
 		/* Should have been caught on the oid check above */
 		g_assert_not_reached ();
-		r = GKR_PARSE_UNRECOGNIZED;
+		r = GKR_PKIX_UNRECOGNIZED;
 		break;
 	};
 
-	if (r != GKR_PARSE_SUCCESS) {
+	if (r != GKR_PKIX_SUCCESS) {
 		ret = r;
 		goto done;
 	}
 
 	/* Read out the key creation paramaters */
-	key_deriv_algo = gkr_pkix_asn1_read_quark (asn, "keyDerivationFunc.algorithm");
+	key_deriv_algo = gkr_pkix_asn1_read_oid (asn, "keyDerivationFunc.algorithm");
 	if (!key_deriv_algo)
 		goto done;
 	if (key_deriv_algo != OID_PBKDF2) {
 		g_message ("unsupported key derivation algorithm: %s", g_quark_to_string (key_deriv_algo));
-		ret = GKR_PARSE_UNRECOGNIZED;
+		ret = GKR_PKIX_UNRECOGNIZED;
 		goto done;
 	}
 
@@ -1083,11 +1299,10 @@
 	                                &beg, &end) != ASN1_SUCCESS)
 		goto done;
 	
-	ret = setup_pkcs5_pbkdf2_params (parser, password, data + beg, 
-	                                 end - beg + 1, algo, *cih);
+	ret = setup_pkcs5_pbkdf2_params (password, data + beg, end - beg + 1, algo, *cih);
 
 done:
-	if (ret != GKR_PARSE_SUCCESS && *cih) {
+	if (ret != GKR_PKIX_SUCCESS && *cih) {
 		gcry_cipher_close (*cih);
 		*cih = NULL;
 	}
@@ -1098,14 +1313,13 @@
 	return ret;
 }
 
-GkrParseResult
-gkr_pkix_der_read_cipher_pkcs12_pbe (GkrPkixParser *parser, int cipher_algo, int cipher_mode, 
-                                     const gchar *password, const guchar *data, gsize n_data, 
-                                     gcry_cipher_hd_t *cih)
+GkrPkixResult
+gkr_pkix_der_read_cipher_pkcs12_pbe (int cipher_algo, int cipher_mode, const gchar *password, 
+                                     const guchar *data, gsize n_data, gcry_cipher_hd_t *cih)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	gcry_error_t gcry;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	const guchar *salt;
 	gsize n_salt;
 	gsize n_block, n_key;
@@ -1113,14 +1327,13 @@
 	guchar *key = NULL;
 	guchar *iv = NULL;
 	
-	g_return_val_if_fail (GKR_IS_PKIX_PARSER (parser), GKR_PARSE_FAILURE);
-	g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (cih != NULL, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (data != NULL && n_data != 0, GKR_PARSE_FAILURE);
-	g_return_val_if_fail (password != NULL, GKR_PARSE_FAILURE);
+	g_return_val_if_fail (cipher_algo != 0 && cipher_mode != 0, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (cih != NULL, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (data != NULL && n_data != 0, GKR_PKIX_FAILURE);
+	g_return_val_if_fail (password != NULL, GKR_PKIX_FAILURE);
 	
 	*cih = NULL;
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	/* Check if we can use this algorithm */
 	if (gcry_cipher_algo_info (cipher_algo, GCRYCTL_TEST_ALGO, NULL, 0) != 0)
@@ -1130,7 +1343,7 @@
 	if (!asn)
 		goto done;
 
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 
 	salt = gkr_pkix_asn1_read_content (asn, data, n_data, "salt", &n_salt);
 	if (!salt)
@@ -1157,10 +1370,10 @@
 		gcry_cipher_setiv (*cih, iv, n_block);
 	gcry_cipher_setkey (*cih, key, n_key);
 	
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
-	if (ret != GKR_PARSE_SUCCESS && *cih) {
+	if (ret != GKR_PKIX_SUCCESS && *cih) {
 		gcry_cipher_close (*cih);
 		*cih = NULL;
 	}

Modified: trunk/pkix/gkr-pkix-der.h
==============================================================================
--- trunk/pkix/gkr-pkix-der.h	(original)
+++ trunk/pkix/gkr-pkix-der.h	Sun Feb  3 01:28:43 2008
@@ -26,44 +26,56 @@
 
 #include <glib.h>
 #include <gcrypt.h>
+#include <libtasn1.h>
 
-#include "gkr-pkix-parser.h"
+#include "gkr-pkix-types.h"
 
 /* -----------------------------------------------------------------------------
  * PRIVATE KEYS 
  */
  
-GkrParseResult  gkr_pkix_der_read_private_key_rsa       (const guchar *data, gsize n_data, 
+GkrPkixResult gkr_pkix_der_read_private_key_rsa         (const guchar *data, gsize n_data, 
                                                          gcry_sexp_t *s_key);
 
-GkrParseResult  gkr_pkix_der_read_private_key_dsa       (const guchar *data, gsize n_data, 
+GkrPkixResult gkr_pkix_der_read_private_key_dsa         (const guchar *data, gsize n_data, 
                                                          gcry_sexp_t *s_key);
 
-GkrParseResult  gkr_pkix_der_read_private_key_dsa_parts (const guchar *keydata, gsize n_keydata,
-							 const guchar *params, gsize n_params, 
+GkrPkixResult gkr_pkix_der_read_private_key_dsa_parts   (const guchar *keydata, gsize n_keydata,
+                                                         const guchar *params, gsize n_params, 
                                                          gcry_sexp_t *s_key);
 
-GkrParseResult  gkr_pkix_der_read_private_key           (const guchar *data, gsize n_data, 
+GkrPkixResult gkr_pkix_der_read_private_key             (const guchar *data, gsize n_data, 
                                                          gcry_sexp_t *s_key);
-                                                         
+
+guchar*       gkr_pkix_der_write_private_key_rsa        (gcry_sexp_t s_key, gsize *n_data);
+
+guchar*       gkr_pkix_der_write_private_key_dsa        (gcry_sexp_t s_key, gsize *len);
+
+guchar*       gkr_pkix_der_write_private_key_dsa_part   (gcry_sexp_t skey, gsize *n_key);
+
+guchar*       gkr_pkix_der_write_private_key_dsa_params (gcry_sexp_t skey, gsize *n_params);
+
+guchar*       gkr_pkix_der_write_private_key            (gcry_sexp_t s_key, gsize *n_data);
+
+
 /* -----------------------------------------------------------------------------
  * PUBLIC KEYS
  */
 
-GkrParseResult  gkr_pkix_der_read_public_key_rsa        (const guchar *data, gsize n_data, 
+GkrPkixResult   gkr_pkix_der_read_public_key_rsa        (const guchar *data, gsize n_data, 
                                                          gcry_sexp_t *s_key);
 
-GkrParseResult  gkr_pkix_der_read_public_key_dsa        (const guchar *data, gsize n_data, 
+GkrPkixResult   gkr_pkix_der_read_public_key_dsa        (const guchar *data, gsize n_data, 
                                                          gcry_sexp_t *s_key);
 
-GkrParseResult  gkr_pkix_der_read_public_key_dsa_parts  (const guchar *keydata, gsize n_keydata,
+GkrPkixResult   gkr_pkix_der_read_public_key_dsa_parts  (const guchar *keydata, gsize n_keydata,
                                                          const guchar *params, gsize n_params,
                                                          gcry_sexp_t *s_key);
                                                          
-GkrParseResult  gkr_pkix_der_read_public_key            (const guchar *data, gsize n_data, 
+GkrPkixResult   gkr_pkix_der_read_public_key            (const guchar *data, gsize n_data, 
                                                          gcry_sexp_t *s_key);
 
-GkrParseResult  gkr_pkix_der_read_public_key_info       (const guchar *data, gsize n_data, 
+GkrPkixResult   gkr_pkix_der_read_public_key_info       (const guchar *data, gsize n_data, 
                                                          gcry_sexp_t *s_key);
 
 guchar*         gkr_pkix_der_write_public_key_rsa       (gcry_sexp_t s_key, gsize *len);
@@ -77,38 +89,38 @@
  * CERTIFICATES
  */
 
-GkrParseResult  gkr_pkix_der_read_certificate           (const guchar *data, gsize n_data, 
+GkrPkixResult   gkr_pkix_der_read_certificate           (const guchar *data, gsize n_data, 
                                                          ASN1_TYPE *asn1);
                                                          
-GkrParseResult  gkr_pkix_der_read_basic_constraints     (const guchar *data, gsize n_data, 
+GkrPkixResult   gkr_pkix_der_read_basic_constraints     (const guchar *data, gsize n_data, 
                                                          gboolean *is_ca, guint *path_len);
 
-GkrParseResult  gkr_pkix_der_read_key_usage             (const guchar *data, gsize n_data, 
+GkrPkixResult   gkr_pkix_der_read_key_usage             (const guchar *data, gsize n_data, 
                                                          guint *key_usage);
 
-GkrParseResult  gkr_pkix_der_read_enhanced_usage        (const guchar *data, gsize n_data, 
+GkrPkixResult   gkr_pkix_der_read_enhanced_usage        (const guchar *data, gsize n_data, 
                                                          GQuark **oids);
 
+guchar*         gkr_pkix_der_write_certificate          (ASN1_TYPE asn1, gsize *n_data);
+
 /* -----------------------------------------------------------------------------
  * CIPHERS
  */
  
-GkrParseResult     gkr_pkix_der_read_cipher                 (GkrPkixParser *parser, GQuark oid_scheme, 
-                                                             const gchar *password, const guchar *data, 
-                                                             gsize n_data, gcry_cipher_hd_t *cih);
-
-GkrParseResult     gkr_pkix_der_read_cipher_pkcs5_pbe       (GkrPkixParser *parser, int cipher_algo, 
-                                                             int cipher_mode, int hash_algo, 
-		                                             const gchar *password, const guchar *data, 
-		                                             gsize n_data, gcry_cipher_hd_t *cih);
-
-GkrParseResult     gkr_pkix_der_read_cipher_pkcs5_pbes2     (GkrPkixParser *parser, const gchar *password, 
+GkrPkixResult      gkr_pkix_der_read_cipher                 (GQuark oid_scheme, const gchar *password, 
                                                              const guchar *data, gsize n_data, 
                                                              gcry_cipher_hd_t *cih);
 
-GkrParseResult     gkr_pkix_der_read_cipher_pkcs12_pbe      (GkrPkixParser *parser, int cipher_algo, 
-                                                             int cipher_mode, const gchar *password,
+GkrPkixResult      gkr_pkix_der_read_cipher_pkcs5_pbe       (int cipher_algo, int cipher_mode, 
+                                                             int hash_algo, const gchar *password, 
                                                              const guchar *data, gsize n_data, 
                                                              gcry_cipher_hd_t *cih);
 
+GkrPkixResult      gkr_pkix_der_read_cipher_pkcs5_pbes2     (const gchar *password, const guchar *data, 
+                                                             gsize n_data, gcry_cipher_hd_t *cih);
+
+GkrPkixResult      gkr_pkix_der_read_cipher_pkcs12_pbe      (int cipher_algo, int cipher_mode, 
+                                                             const gchar *password, const guchar *data, 
+                                                             gsize n_data, gcry_cipher_hd_t *cih);
+
 #endif /*GKRPKIXDER_H_*/

Modified: trunk/pkix/gkr-pkix-openssl.c
==============================================================================
--- trunk/pkix/gkr-pkix-openssl.c	(original)
+++ trunk/pkix/gkr-pkix-openssl.c	Sun Feb  3 01:28:43 2008
@@ -203,7 +203,7 @@
 	return success;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_openssl_decrypt_block (const gchar *dekinfo, const gchar *password, 
                                 const guchar *data, gsize n_data, 
                                 guchar **decrypted, gsize *n_decrypted)
@@ -214,7 +214,7 @@
 	int gcry, ivlen;
 	
 	if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
-		return GKR_PARSE_UNRECOGNIZED;
+		return GKR_PKIX_UNRECOGNIZED;
 		
 	ivlen = gcry_cipher_get_algo_blklen (algo);
 
@@ -225,20 +225,20 @@
 	if (!gkr_crypto_generate_symkey_simple (algo, GCRY_MD_MD5, password, 
 	                                        iv, 8, 1, &key, NULL)) {
 		g_free (iv);
-		return GKR_PARSE_FAILURE;
+		return GKR_PKIX_FAILURE;
 	}
 	
 	/* TODO: Use secure memory */
 	gcry = gcry_cipher_open (&ch, algo, mode, 0);
-	g_return_val_if_fail (!gcry, GKR_PARSE_FAILURE);
+	g_return_val_if_fail (!gcry, GKR_PKIX_FAILURE);
 		
 	gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
-	g_return_val_if_fail (!gcry, GKR_PARSE_UNRECOGNIZED);
+	g_return_val_if_fail (!gcry, GKR_PKIX_UNRECOGNIZED);
 	gkr_secure_free (key);
 
 	/* 16 = 128 bits */
 	gcry = gcry_cipher_setiv (ch, iv, ivlen);
-	g_return_val_if_fail (!gcry, GKR_PARSE_UNRECOGNIZED);
+	g_return_val_if_fail (!gcry, GKR_PKIX_UNRECOGNIZED);
 	g_free (iv);
 	
 	/* Allocate output area */
@@ -248,10 +248,10 @@
 	gcry = gcry_cipher_decrypt (ch, *decrypted, *n_decrypted, (void*)data, n_data);
 	if (gcry) {
 		gkr_secure_free (*decrypted);
-		g_return_val_if_reached (GKR_PARSE_FAILURE);
+		g_return_val_if_reached (GKR_PKIX_FAILURE);
 	}
 	
 	gcry_cipher_close (ch);
 	
-	return GKR_PARSE_SUCCESS;
+	return GKR_PKIX_SUCCESS;
 }

Modified: trunk/pkix/gkr-pkix-openssl.h
==============================================================================
--- trunk/pkix/gkr-pkix-openssl.h	(original)
+++ trunk/pkix/gkr-pkix-openssl.h	Sun Feb  3 01:28:43 2008
@@ -30,7 +30,7 @@
 
 int               gkr_pkix_openssl_parse_algo       (const gchar *name, int *mode);
 
-GkrParseResult    gkr_pkix_openssl_decrypt_block    (const gchar *dekinfo, const gchar *password, 
+GkrPkixResult    gkr_pkix_openssl_decrypt_block    (const gchar *dekinfo, const gchar *password, 
                                                      const guchar *data, gsize n_data, 
                                                      guchar **decrypted, gsize *n_decrypted);
 

Modified: trunk/pkix/gkr-pkix-parser.c
==============================================================================
--- trunk/pkix/gkr-pkix-parser.c	(original)
+++ trunk/pkix/gkr-pkix-parser.c	Sun Feb  3 01:28:43 2008
@@ -143,7 +143,7 @@
  
 static const gchar*
 enum_next_password (GkrPkixParser *parser, GQuark loc, gkrunique unique, 
-                    GkrParsedType type, const gchar *label, PasswordState *state)
+                    GQuark type, const gchar *label, PasswordState *state)
 {
 	GkrPkixParserPrivate *pv = GKR_PKIX_PARSER_GET_PRIVATE (parser);
 	gboolean first = FALSE;
@@ -230,7 +230,7 @@
 
 static void
 fire_parsed_partial (GkrPkixParser *parser, GQuark location, 
-                     gkrconstunique unique, GkrParsedType type)
+                     gkrconstunique unique, GQuark type)
 {
 	gboolean owned = FALSE;
 	
@@ -242,11 +242,10 @@
 
 static void
 fire_parsed_sexp (GkrPkixParser *parser, GQuark location, gkrconstunique unique, 
-                  GkrParsedType type, gcry_sexp_t sexp)
+                  GQuark type, gcry_sexp_t sexp)
 {
 	gboolean owned = FALSE;
 	
-	g_assert (location);
 	g_assert (sexp);
 	g_assert (type);
 	
@@ -258,11 +257,10 @@
 
 static void
 fire_parsed_asn1 (GkrPkixParser *parser, GQuark location, gkrconstunique unique, 
-                  GkrParsedType type, ASN1_TYPE asn1)
+                  GQuark type, ASN1_TYPE asn1)
 {
 	gboolean owned = FALSE;
 	
-	g_assert (location);
 	g_assert (asn1);
 	g_assert (type);
 	
@@ -300,7 +298,7 @@
 
 static gboolean 
 gkr_pkix_parser_parsed_partial (GkrPkixParser *parser, GQuark loc, gkrconstunique unique, 
-                                GkrParsedType type)
+                                GQuark type)
 {
 	/* Didn't take ownership of the data */
 	return FALSE;
@@ -308,7 +306,7 @@
 
 static gboolean 
 gkr_pkix_parser_parsed_asn1 (GkrPkixParser *parser, GQuark loc, gkrconstunique unique, 
-                             GkrParsedType type, ASN1_TYPE asn1)
+                             GQuark type, ASN1_TYPE asn1)
 {
 	/* Didn't take ownership of the data */
 	return FALSE;
@@ -316,7 +314,7 @@
 
 static gboolean 
 gkr_pkix_parser_parsed_sexp (GkrPkixParser *parser, GQuark loc, gkrconstunique unique, 
-                             GkrParsedType type, gcry_sexp_t sexp)
+                             GQuark type, gcry_sexp_t sexp)
 {
 	/* Didn't take ownership of the data */
 	return FALSE;
@@ -324,7 +322,7 @@
 
 static gchar*
 gkr_pkix_parser_ask_password (GkrPkixParser *parser, GQuark loc, gkrconstunique unique,
-                              GkrParsedType type, const gchar *details, guint n_prompts)
+                              GQuark type, const gchar *details, guint n_prompts)
 {
 	return NULL;
 }
@@ -406,30 +404,30 @@
 gkr_pkix_parser_parse (GkrPkixParser *parser, GQuark loc, const guchar *data, 
                        gsize n_data, GError **err)
 {
-	GkrParseResult ret;
+	GkrPkixResult ret;
 
 	g_return_val_if_fail (GKR_IS_PKIX_PARSER (parser), FALSE);
 	g_return_val_if_fail (loc != 0, FALSE);
 	g_return_val_if_fail (data != NULL, FALSE);
 	g_return_val_if_fail (!err || !*err, FALSE);
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	if (n_data > 0) {
 		ret = gkr_pkix_parser_der (parser, loc, data, n_data);
-		if (ret == GKR_PARSE_UNRECOGNIZED)
+		if (ret == GKR_PKIX_UNRECOGNIZED)
 			ret = gkr_pkix_parser_pem (parser, loc, data, n_data);
 	}
 	
-	if (ret == GKR_PARSE_SUCCESS)
+	if (ret == GKR_PKIX_SUCCESS)
 		return TRUE;
 		
 	switch (ret) {
-	case GKR_PARSE_UNRECOGNIZED:
+	case GKR_PKIX_UNRECOGNIZED:
 		g_set_error (err, GKR_PKIX_PARSE_ERROR, ret, "%s",
 		             _("Unrecognized or unsupported file."));
 		return FALSE;
-	case GKR_PARSE_FAILURE:
+	case GKR_PKIX_FAILURE:
 		g_set_error (err, GKR_PKIX_PARSE_ERROR, ret, "%s",
 		             _("Could not parse invalid or corrupted file."));
 		return FALSE;
@@ -440,11 +438,11 @@
 }
 
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_der (GkrPkixParser *parser, GQuark loc, 
                      const guchar *data, gsize n_data)
 {
-	GkrParseResult ret = GKR_PARSE_UNRECOGNIZED;
+	GkrPkixResult ret = GKR_PKIX_UNRECOGNIZED;
 	
 	/*
 	 * It's pretty much impossible to know what DER data belongs to 
@@ -457,23 +455,23 @@
 	 */
 	
 	ret = gkr_pkix_parser_der_pkcs12 (parser, loc, data, n_data);
-	if (ret != GKR_PARSE_UNRECOGNIZED)
+	if (ret != GKR_PKIX_UNRECOGNIZED)
 		goto done;
 
 	ret = gkr_pkix_parser_der_certificate (parser, loc, data, n_data);
-	if (ret != GKR_PARSE_UNRECOGNIZED)
+	if (ret != GKR_PKIX_UNRECOGNIZED)
 		goto done;
 
 	ret = gkr_pkix_parser_der_private_key (parser, loc, data, n_data);
-	if (ret != GKR_PARSE_UNRECOGNIZED)
+	if (ret != GKR_PKIX_UNRECOGNIZED)
 		goto done;
 		
 	ret = gkr_pkix_parser_der_pkcs8 (parser, loc, data, n_data);
-	if (ret != GKR_PARSE_UNRECOGNIZED)
+	if (ret != GKR_PKIX_UNRECOGNIZED)
 		goto done;
 		
 	ret = gkr_pkix_parser_der_pkcs7 (parser, loc, data, n_data);
-	if (ret != GKR_PARSE_UNRECOGNIZED)
+	if (ret != GKR_PKIX_UNRECOGNIZED)
 		goto done;
 		
 done:
@@ -481,44 +479,16 @@
 }
 
 const gchar*
-gkr_pkix_parsed_type_to_string (GkrParsedType type)
+gkr_pkix_parsed_type_to_display (GQuark type)
 {
-	switch (type) {
-	case GKR_PARSED_PRIVATE_KEY:
-		return "private-key";
-	case GKR_PARSED_CERTIFICATE:
-		return "certificate";
-	case GKR_PARSED_UNKNOWN:
-		return "";
-	default:
-		g_return_val_if_reached ("");
-	};	
-}
-
-const gchar*
-gkr_pkix_parsed_type_to_display (GkrParsedType type)
-{
-	switch (type) {
-	case GKR_PARSED_PRIVATE_KEY:
+	if (type == GKR_PKIX_PRIVATE_KEY)
 		return _("private key");
-	case GKR_PARSED_CERTIFICATE:
+	else if (type == GKR_PKIX_CERTIFICATE)
 		return _("certificate");
-	default:
-		g_return_val_if_reached ("");
-	};	
-}
-
-GkrParsedType
-gkr_pkix_parsed_type_from_string (const gchar *string)
-{
-	if (!string || !string[0])
-		return GKR_PARSED_UNKNOWN;
-	else if (g_str_equal ("private-key", string))
-		return GKR_PARSED_PRIVATE_KEY;
-	else if (g_str_equal ("certificate", string))
-		return GKR_PARSED_CERTIFICATE;
+	else if (type == GKR_PKIX_PUBLIC_KEY)
+		return _("public key");
 	else
-		g_return_val_if_reached (GKR_PARSED_UNKNOWN);
+		g_return_val_if_reached ("");
 }
 
 gboolean
@@ -563,33 +533,33 @@
  * PRIVATE KEYS
  */
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_der_private_key (GkrPkixParser *parser, GQuark loc,
                                  const guchar *data, gsize n_data)
 {
 	gkrunique unique;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	gcry_sexp_t s_key = NULL;
 	
 	unique = gkr_unique_new_digest (data, n_data);
 	
 	ret = gkr_pkix_der_read_private_key_rsa (data, n_data, &s_key);
-	if (ret == GKR_PARSE_UNRECOGNIZED)
+	if (ret == GKR_PKIX_UNRECOGNIZED)
 		ret = gkr_pkix_der_read_private_key_dsa (data, n_data, &s_key);
-	if (ret == GKR_PARSE_SUCCESS)
-		fire_parsed_sexp (parser, loc, unique, GKR_PARSED_PRIVATE_KEY, s_key);
+	if (ret == GKR_PKIX_SUCCESS)
+		fire_parsed_sexp (parser, loc, unique, GKR_PKIX_PRIVATE_KEY, s_key);
 		
 	gkr_unique_free (unique);
 	
 	return ret;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_der_pkcs8_plain (GkrPkixParser *parser, GQuark loc, 
                        gkrunique unique, const guchar *data, gsize n_data)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	int algorithm;
 	GQuark key_algo;
 	const guchar *keydata;
@@ -598,16 +568,16 @@
 	gsize n_params;
 	gcry_sexp_t s_key = NULL;
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-8-PrivateKeyInfo", data, n_data);
 	if (!asn)
 		goto done;
 
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 	algorithm = 0;
 		
-	key_algo = gkr_pkix_asn1_read_quark (asn, "privateKeyAlgorithm.algorithm");
+	key_algo = gkr_pkix_asn1_read_oid (asn, "privateKeyAlgorithm.algorithm");
   	if (!key_algo)
   		goto done;
   	else if (key_algo == OID_PKIX1_RSA)
@@ -616,7 +586,7 @@
   		algorithm = GCRY_PK_DSA;
   		
   	if (!algorithm) {
-  		ret = GKR_PARSE_UNRECOGNIZED;
+  		ret = GKR_PKIX_UNRECOGNIZED;
   		goto done;
   	}
 
@@ -627,10 +597,10 @@
 	params = gkr_pkix_asn1_read_element (asn, data, n_data, "privateKeyAlgorithm.parameters", 
 	                                     &n_params);
 		
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
-	if (ret == GKR_PARSE_SUCCESS) {		
+	if (ret == GKR_PKIX_SUCCESS) {		
 		switch (algorithm) {
 		case GCRY_PK_RSA:
 			ret = gkr_pkix_der_read_private_key_rsa (keydata, n_keydata, &s_key);
@@ -639,22 +609,22 @@
 			/* Try the normal sane format */
 			ret = gkr_pkix_der_read_private_key_dsa (keydata, n_keydata, &s_key);
 			
-			/* Otherwise try the strange freaky format, everyone seems to like */
-			if (ret == GKR_PARSE_UNRECOGNIZED && params && n_params)
+			/* Otherwise try the two part format that everyone seems to like */
+			if (ret == GKR_PKIX_UNRECOGNIZED && params && n_params)
 				ret = gkr_pkix_der_read_private_key_dsa_parts (keydata, n_keydata, 
 				                                               params, n_params, &s_key);
 			
 			break;
 		default:
 			g_message ("invalid or unsupported key type in PKCS#8 key");
-			ret = GKR_PARSE_UNRECOGNIZED;
+			ret = GKR_PKIX_UNRECOGNIZED;
 			break;
 		};
 		
-		if (ret == GKR_PARSE_SUCCESS)
-			fire_parsed_sexp (parser, loc, unique, GKR_PARSED_PRIVATE_KEY, s_key);
+		if (ret == GKR_PKIX_SUCCESS)
+			fire_parsed_sexp (parser, loc, unique, GKR_PKIX_PRIVATE_KEY, s_key);
 		
-	} else if (ret == GKR_PARSE_FAILURE) {
+	} else if (ret == GKR_PKIX_FAILURE) {
 		g_message ("invalid PKCS#8 key");
 	}
 	
@@ -663,12 +633,12 @@
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_der_pkcs8_plain (GkrPkixParser *parser, GQuark location, 
                                  const guchar *data, gsize n_data)
 {
 	gkrunique unique;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	
 	unique = gkr_unique_new_digest (data, n_data);
 	ret = parse_der_pkcs8_plain (parser, location, unique, data, n_data);
@@ -677,7 +647,7 @@
 	return ret;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_der_pkcs8_encrypted (GkrPkixParser *parser, GQuark location, 
                            gkrunique unique, const guchar *data, gsize n_data)
 {
@@ -685,7 +655,7 @@
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	gcry_cipher_hd_t cih = NULL;
 	gcry_error_t gcry;
-	GkrParseResult ret, r;
+	GkrPkixResult ret, r;
 	GQuark scheme;
 	guchar *crypted = NULL;
 	const guchar *params;
@@ -693,16 +663,16 @@
 	const gchar *password;
 	gint l;
 
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-8-EncryptedPrivateKeyInfo", data, n_data);
 	if (!asn)
 		goto done;
 
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 
 	/* Figure out the type of encryption */
-	scheme = gkr_pkix_asn1_read_quark (asn, "encryptionAlgorithm.algorithm");
+	scheme = gkr_pkix_asn1_read_oid (asn, "encryptionAlgorithm.algorithm");
 	if (!scheme)
 		goto done;
 		
@@ -713,24 +683,23 @@
 		
 		g_assert (cih == NULL);
 		
-	        password = enum_next_password (parser, location, unique, GKR_PARSED_PRIVATE_KEY, NULL, &pstate);
+	        password = enum_next_password (parser, location, unique, GKR_PKIX_PRIVATE_KEY, NULL, &pstate);
 
         	/* If no password is available, we still know it's a key, so 'partial' parse */
 	        if (!password) {
-	        	fire_parsed_partial (parser, location, unique, GKR_PARSED_PRIVATE_KEY);
-	        	ret = GKR_PARSE_SUCCESS;
+	        	fire_parsed_partial (parser, location, unique, GKR_PKIX_PRIVATE_KEY);
+	        	ret = GKR_PKIX_SUCCESS;
 	        	goto done; 
 	        }
 	        
 		/* 
 		 * Parse the encryption stuff into a cipher. 
 		 */
-		r = gkr_pkix_der_read_cipher (parser, scheme, password, 
-		                              params, n_params, &cih);
-		if (r == GKR_PARSE_UNRECOGNIZED) {
-			ret = GKR_PARSE_FAILURE;
+		r = gkr_pkix_der_read_cipher (scheme, password, params, n_params, &cih);
+		if (r == GKR_PKIX_UNRECOGNIZED) {
+			ret = GKR_PKIX_FAILURE;
 			goto done;
-		} else if (r != GKR_PARSE_SUCCESS) {
+		} else if (r != GKR_PKIX_SUCCESS) {
 			ret = r;
 			goto done;
 		}
@@ -759,7 +728,7 @@
 		gkr_secure_free (crypted);
 		crypted = NULL;
 		
-		if (r != GKR_PARSE_UNRECOGNIZED) {
+		if (r != GKR_PKIX_UNRECOGNIZED) {
 			ret = r;
 			break;
 		}
@@ -777,12 +746,12 @@
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_der_pkcs8_encrypted (GkrPkixParser *parser, GQuark location, 
                                      const guchar *data, gsize n_data)
 {
 	gkrunique unique;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	
 	unique = gkr_unique_new_digest (data, n_data);
 	ret = parse_der_pkcs8_encrypted (parser, location, unique, data, n_data);
@@ -791,16 +760,16 @@
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_der_pkcs8 (GkrPkixParser *parser, GQuark loc, const guchar *data, 
                            gsize n_data)
 {
 	gkrunique unique;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	
 	unique = gkr_unique_new_digest (data, n_data);
 	ret = parse_der_pkcs8_plain (parser, loc, unique, data, n_data);
-	if (ret == GKR_PARSE_UNRECOGNIZED)
+	if (ret == GKR_PKIX_UNRECOGNIZED)
 		ret = parse_der_pkcs8_encrypted (parser, loc, unique, data, n_data);
 	gkr_unique_free (unique);
 	
@@ -811,19 +780,19 @@
  * X509 stuff
  */
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_der_certificate (GkrPkixParser *parser, GQuark loc, 
                                  const guchar *data, gsize n_data)
 {
 	gkrunique unique;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	ASN1_TYPE asn1;
 	
 	unique = gkr_unique_new_digest (data, n_data);
 
 	ret = gkr_pkix_der_read_certificate (data, n_data, &asn1);	
-	if(ret == GKR_PARSE_SUCCESS)
-		fire_parsed_asn1 (parser, loc, unique, GKR_PARSED_CERTIFICATE, asn1);
+	if(ret == GKR_PKIX_SUCCESS)
+		fire_parsed_asn1 (parser, loc, unique, GKR_PKIX_CERTIFICATE, asn1);
 	gkr_unique_free (unique);
 	
 	return ret;
@@ -833,22 +802,22 @@
  * CONTAINER FORMATS
  */
 
-static GkrParseResult
+static GkrPkixResult
 parse_pkcs12_cert_bag (GkrPkixParser *parser, GQuark loc, gkrunique uni, const guchar *data, gsize n_data)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	ASN1_TYPE casn = ASN1_TYPE_EMPTY;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	const guchar *certificate;
 	gsize n_certificate;
 
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-12-CertBag", data, n_data);
 	if (!asn)
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 	
 	certificate = gkr_pkix_asn1_read_content (asn, data, n_data, "certValue", &n_certificate);
 	if (!certificate)
@@ -863,8 +832,8 @@
 		goto done;
 	
 	ret = gkr_pkix_der_read_certificate (certificate, n_certificate, &casn);
-	if(ret == GKR_PARSE_SUCCESS)
-		fire_parsed_asn1 (parser, loc, uni, GKR_PARSED_CERTIFICATE, casn);
+	if(ret == GKR_PKIX_SUCCESS)
+		fire_parsed_asn1 (parser, loc, uni, GKR_PKIX_CERTIFICATE, casn);
 		
 done:
 	if (asn)
@@ -873,11 +842,11 @@
 	return ret;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_pkcs12_bag (GkrPkixParser *parser, GQuark loc, gkrunique uni, const guchar *data, gsize n_data)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GkrParseResult ret, r;
+	GkrPkixResult ret, r;
 	int count = 0;
 	GQuark oid;
 	gchar *part;
@@ -885,13 +854,13 @@
 	gsize n_element;
 	int res, i;
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-12-SafeContents", data, n_data);
 	if (!asn)
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 	
 	/* Get the number of elements in this bag */
 	res = asn1_number_of_elements (asn, "", &count);
@@ -905,7 +874,7 @@
 	for (i = 0; i < count; ++i)
 	{
 		part = g_strdup_printf ("?%u.bagId", i + 1);
-		oid = gkr_pkix_asn1_read_quark (asn, part);
+		oid = gkr_pkix_asn1_read_oid (asn, part);
 		g_free (part);
 		
 		if (!oid)
@@ -932,16 +901,16 @@
 								
 		/* TODO: OID_PKCS12_BAG_CRL */
 		} else {
-			r = GKR_PARSE_UNRECOGNIZED;
+			r = GKR_PKIX_UNRECOGNIZED;
 		}
 		 
-		if (r == GKR_PARSE_FAILURE) {
+		if (r == GKR_PKIX_FAILURE) {
 			ret = r;
 			goto done;
 		}
 	}
 
-	ret = GKR_PARSE_SUCCESS;	
+	ret = GKR_PKIX_SUCCESS;	
 		
 done:
 	if (asn)
@@ -950,7 +919,7 @@
 	return ret;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_pkcs12_encrypted_bag (GkrPkixParser *parser, GQuark loc, gkrunique uni, 
                             const guchar *data, gsize n_data)
 {
@@ -958,7 +927,7 @@
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	gcry_cipher_hd_t cih = NULL;
 	gcry_error_t gcry;
-	GkrParseResult ret, r;
+	GkrPkixResult ret, r;
 	guchar *crypted = NULL;
 	const guchar *params;
 	gsize n_params, n_crypted;
@@ -966,16 +935,16 @@
 	GQuark scheme;
 	gint l;
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-7-EncryptedData", data, n_data);
 	if (!asn)
 		goto done;
 	
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 		
 	/* Check the encryption schema OID */
-	scheme = gkr_pkix_asn1_read_quark (asn, "encryptedContentInfo.contentEncryptionAlgorithm.algorithm");
+	scheme = gkr_pkix_asn1_read_oid (asn, "encryptedContentInfo.contentEncryptionAlgorithm.algorithm");
 	if (!scheme) 
 		goto done;	
 
@@ -988,20 +957,19 @@
 		
 		g_assert (cih == NULL);
 		
-	        password = enum_next_password (parser, loc, uni, GKR_PARSED_UNKNOWN, NULL, &pstate);
+	        password = enum_next_password (parser, loc, uni, 0, NULL, &pstate);
 	        if (!password) {
-	        	fire_parsed_partial (parser, loc, uni, GKR_PARSED_UNKNOWN);
-	        	ret = GKR_PARSE_SUCCESS;
+	        	fire_parsed_partial (parser, loc, uni, 0);
+	        	ret = GKR_PKIX_SUCCESS;
 	        	goto done; 
 	        }
 	        
 		/* Parse the encryption stuff into a cipher. */
-		r = gkr_pkix_der_read_cipher (parser, scheme, password, 
-		                              params, n_params, &cih);
-		if (r == GKR_PARSE_UNRECOGNIZED) {
-			ret = GKR_PARSE_FAILURE;
+		r = gkr_pkix_der_read_cipher (scheme, password, params, n_params, &cih);
+		if (r == GKR_PKIX_UNRECOGNIZED) {
+			ret = GKR_PKIX_FAILURE;
 			goto done;
-		} else if (r != GKR_PARSE_SUCCESS) {
+		} else if (r != GKR_PKIX_SUCCESS) {
 			ret = r;
 			goto done;
 		}
@@ -1030,7 +998,7 @@
 		gkr_secure_free (crypted);
 		crypted = NULL;
 		
-		if (r != GKR_PARSE_UNRECOGNIZED) {
+		if (r != GKR_PKIX_UNRECOGNIZED) {
 			ret = r;
 			break;
 		}
@@ -1048,11 +1016,11 @@
 	return ret;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_pkcs12_safe (GkrPkixParser *parser, GQuark loc, const guchar *data, gsize n_data)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GkrParseResult ret, r;
+	GkrPkixResult ret, r;
 	const guchar *bag;
 	gkrunique uni = NULL;
 	gsize n_bag;
@@ -1060,13 +1028,13 @@
 	GQuark oid;
 	guint i;
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-12-AuthenticatedSafe", data, n_data);
 	if (!asn)
 		goto done;
 		
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 	
 	/*
 	 * Inside each PKCS12 safe there are multiple bags. 
@@ -1074,7 +1042,7 @@
 	for (i = 0; TRUE; ++i) {
 		
 		part = g_strdup_printf ("?%u.contentType", i + 1);
-		oid = gkr_pkix_asn1_read_quark (asn, part);
+		oid = gkr_pkix_asn1_read_oid (asn, part);
 		g_free (part);
 		
 		/* All done? no more bags */
@@ -1111,16 +1079,16 @@
 		/* Hmmmm, not sure what this is */
 		} else {
 			g_warning ("unrecognized type of safe content in pkcs12: %s", g_quark_to_string (oid));
-			r = GKR_PARSE_UNRECOGNIZED;
+			r = GKR_PKIX_UNRECOGNIZED;
 		}
 		
-		if (r == GKR_PARSE_FAILURE) {
+		if (r == GKR_PKIX_FAILURE) {
 			ret = r;
 			goto done;
 		}
 	}
 	
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
 	if (asn)
@@ -1131,22 +1099,22 @@
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_der_pkcs12 (GkrPkixParser *parser, GQuark loc, const guchar *data, gsize n_data)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	const guchar* content = NULL;
 	gsize n_content;
 	GQuark oid;
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-12-PFX", data, n_data);
 	if (!asn)
 		goto done;
 
-	oid = gkr_pkix_asn1_read_quark (asn, "authSafe.contentType");
+	oid = gkr_pkix_asn1_read_oid (asn, "authSafe.contentType");
 	if (!oid)
 		goto done;
 		
@@ -1176,25 +1144,25 @@
 	return ret;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_pkcs7_signed_data (GkrPkixParser *parser, GQuark loc, gkrunique uni, 
                          const guchar *data, gsize n_data)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
 	ASN1_TYPE casn = ASN1_TYPE_EMPTY;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	gchar *part;
 	const guchar *certificate;
 	gsize n_certificate;
 	int i;
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-7-SignedData", data, n_data);
 	if (!asn)
 		goto done;
 
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 	
 	for (i = 0; TRUE; ++i) {
 			
@@ -1207,15 +1175,15 @@
 			break;
 	
 		ret = gkr_pkix_der_read_certificate (certificate, n_certificate, &casn);
-		if (ret == GKR_PARSE_SUCCESS)
-			fire_parsed_asn1 (parser, loc, uni, GKR_PARSED_CERTIFICATE, casn);
-		if (ret == GKR_PARSE_FAILURE)
+		if (ret == GKR_PKIX_SUCCESS)
+			fire_parsed_asn1 (parser, loc, uni, GKR_PKIX_CERTIFICATE, casn);
+		if (ret == GKR_PKIX_FAILURE)
 			goto done;
 	}
 	
 	/* TODO: Parse out all the CRLs */
 	
-	ret = GKR_PARSE_SUCCESS;
+	ret = GKR_PKIX_SUCCESS;
 	
 done:
 	if (asn)
@@ -1223,25 +1191,25 @@
 	return ret;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_der_pkcs7 (GkrPkixParser *parser, GQuark loc, gkrunique uni, 
                  const guchar *data, gsize n_data)
 {
 	ASN1_TYPE asn = ASN1_TYPE_EMPTY;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	const guchar* content = NULL;
 	gsize n_content;
 	GQuark oid;
 	
-	ret = GKR_PARSE_UNRECOGNIZED;
+	ret = GKR_PKIX_UNRECOGNIZED;
 	
 	asn = gkr_pkix_asn1_decode ("PKIX1.pkcs-7-ContentInfo", data, n_data);
 	if (!asn)
 		goto done;
 
-	ret = GKR_PARSE_FAILURE;
+	ret = GKR_PKIX_FAILURE;
 
-	oid = gkr_pkix_asn1_read_quark (asn, "contentType");
+	oid = gkr_pkix_asn1_read_oid (asn, "contentType");
 	if (!oid)
 		goto done;
 
@@ -1263,10 +1231,10 @@
 	return ret;
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_der_pkcs7 (GkrPkixParser *parser, GQuark loc, const guchar *data, gsize n_data)
 {
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	gkrunique uni;
 	
 	uni = gkr_unique_new_digest (data, n_data);
@@ -1279,10 +1247,10 @@
 typedef struct {
 	GkrPkixParser *parser;
 	GQuark location;
-	GkrParseResult result;
+	GkrPkixResult result;
 } ParserCtx;
 
-static GkrParsedType
+static GQuark
 pem_to_parsed_type (gint type)
 {
 	if (type == PEM_RSA_PRIVATE_KEY ||
@@ -1290,37 +1258,37 @@
 	    type == PEM_ANY_PRIVATE_KEY ||
 	    type == PEM_PRIVATE_KEY ||
 	    type == PEM_ENCRYPTED_PRIVATE_KEY)
-	    	return GKR_PARSED_PRIVATE_KEY;
+	    	return GKR_PKIX_PRIVATE_KEY;
 
 	else if (type == PEM_CERTIFICATE)
-		return GKR_PARSED_CERTIFICATE;
+		return GKR_PKIX_CERTIFICATE;
 		
 	else if (type == PEM_PKCS7 ||
 	         type == PEM_PKCS12)
-		return GKR_PARSED_UNKNOWN;
+		return 0;
 
 	return 0;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_plain_pem (GkrPkixParser *parser, GQuark location, gkrunique unique, 
                  GQuark type, const guchar *data, gsize n_data)
 {
-	GkrParseResult res;
+	GkrPkixResult res;
 	gcry_sexp_t s_key = NULL;
 	ASN1_TYPE asn1 = NULL;
-	GkrParsedType parsed = GKR_PARSED_UNKNOWN;
+	GQuark parsed = 0;
 	
 	if (type == PEM_RSA_PRIVATE_KEY) {
-		parsed = GKR_PARSED_PRIVATE_KEY;
+		parsed = GKR_PKIX_PRIVATE_KEY;
 		res = gkr_pkix_der_read_private_key_rsa (data, n_data, &s_key);
 
 	} else if (type == PEM_DSA_PRIVATE_KEY) {
-		parsed = GKR_PARSED_PRIVATE_KEY;
+		parsed = GKR_PKIX_PRIVATE_KEY;
 		res = gkr_pkix_der_read_private_key_dsa (data, n_data, &s_key);
 
 	} else if (type == PEM_ANY_PRIVATE_KEY) {
-		parsed = GKR_PARSED_PRIVATE_KEY;
+		parsed = GKR_PKIX_PRIVATE_KEY;
 		res = gkr_pkix_der_read_private_key (data, n_data, &s_key);
 	
 	} else if (type == PEM_PRIVATE_KEY) {
@@ -1330,7 +1298,7 @@
 		return parse_der_pkcs8_encrypted (parser, location, unique, data, n_data);
 		
 	} else if (type == PEM_CERTIFICATE) {
-		parsed = GKR_PARSED_CERTIFICATE;
+		parsed = GKR_PKIX_CERTIFICATE;
 		res = gkr_pkix_der_read_certificate (data, n_data, &asn1);
 		
 	} else if (type == PEM_PKCS7) {
@@ -1340,10 +1308,10 @@
 		return gkr_pkix_parser_der_pkcs12 (parser, location, data, n_data);
 		
 	} else {
-		res = GKR_PARSE_UNRECOGNIZED;
+		res = GKR_PKIX_UNRECOGNIZED;
 	}
 	
-	if (res == GKR_PARSE_SUCCESS) {
+	if (res == GKR_PKIX_SUCCESS) {
 		g_assert (s_key || asn1);
 		g_assert (parsed);
 		
@@ -1356,13 +1324,13 @@
 	return res;
 }
 
-static GkrParseResult
+static GkrPkixResult
 parse_encrypted_pem (GkrPkixParser *parser, GQuark location, gkrunique unique, 
                      GQuark type, GHashTable *headers, const guchar *data, gsize n_data)
 {
 	PasswordState pstate = PASSWORD_STATE_INIT;
-	GkrParsedType parsed;
-	GkrParseResult ret;
+	GQuark parsed;
+	GkrPkixResult ret;
 	const gchar *val;
 	const gchar *password;
 	guchar *decrypted;
@@ -1377,12 +1345,12 @@
 	val = g_hash_table_lookup (headers, "DEK-Info");
 	if (!val) {
 		g_message ("missing encryption header");
-		return GKR_PARSE_FAILURE;
+		return GKR_PKIX_FAILURE;
 	}
 	
 	parsed = pem_to_parsed_type (type);
 	if (!parsed) 
-		return GKR_PARSE_UNRECOGNIZED;
+		return GKR_PKIX_UNRECOGNIZED;
 		
 	while (!gkr_async_is_stopping ()) {
 
@@ -1391,7 +1359,7 @@
         	/* If no password is available, we still know what it was, so 'partial' parse */
 	        if (!password) {
 	        	fire_parsed_partial (parser, location, unique, parsed);
-	        	return GKR_PARSE_SUCCESS;
+	        	return GKR_PKIX_SUCCESS;
 	        }
 		
 		decrypted = NULL;
@@ -1401,7 +1369,7 @@
 		res = gkr_pkix_openssl_decrypt_block (val, password, data, n_data, 
 		                                      &decrypted, &n_decrypted);
 		if (!res)
-			return GKR_PARSE_FAILURE;
+			return GKR_PKIX_FAILURE;
 			
 		g_assert (decrypted);
 		
@@ -1414,11 +1382,11 @@
 		ret = parse_plain_pem (parser, location, unique, type, decrypted, n_decrypted);
 		gkr_secure_free (decrypted);
 
-		if (ret != GKR_PARSE_UNRECOGNIZED)
+		if (ret != GKR_PKIX_UNRECOGNIZED)
 			return ret;		
 	}
 	
-	return GKR_PARSE_FAILURE;
+	return GKR_PKIX_FAILURE;
 }
 
 static void
@@ -1426,7 +1394,7 @@
                  GHashTable *headers, gpointer user_data)
 {
 	ParserCtx *ctx = (ParserCtx*)user_data;
-	GkrParseResult res = GKR_PARSE_FAILURE;
+	GkrPkixResult res = GKR_PKIX_FAILURE;
 	gboolean encrypted = FALSE;
 	gkrunique unique;
 	const gchar *val;
@@ -1448,27 +1416,27 @@
 		                       type, data, n_data);
 	}
 	
-	if (res == GKR_PARSE_FAILURE) {
+	if (res == GKR_PKIX_FAILURE) {
 		ctx->result = res;
-	} else if (ctx->result == GKR_PARSE_UNRECOGNIZED)
+	} else if (ctx->result == GKR_PKIX_UNRECOGNIZED)
 		ctx->result = res;
 		
 	gkr_unique_free (unique);
 }
 
-GkrParseResult
+GkrPkixResult
 gkr_pkix_parser_pem (GkrPkixParser *parser, GQuark loc, const guchar *data, gsize n_data)
 {
-	ParserCtx ctx = { parser, loc, GKR_PARSE_UNRECOGNIZED };
+	ParserCtx ctx = { parser, loc, GKR_PKIX_UNRECOGNIZED };
 	guint found;
 	
 	if (n_data == 0)
-		return GKR_PARSE_UNRECOGNIZED;
+		return GKR_PKIX_UNRECOGNIZED;
 	
 	found = gkr_pkix_pem_parse (data, n_data, handle_pem_data, &ctx);
 	
 	if (found == 0)
-		return GKR_PARSE_UNRECOGNIZED;
+		return GKR_PKIX_UNRECOGNIZED;
 		
 	return ctx.result;
 }

Modified: trunk/pkix/gkr-pkix-parser.h
==============================================================================
--- trunk/pkix/gkr-pkix-parser.h	(original)
+++ trunk/pkix/gkr-pkix-parser.h	Sun Feb  3 01:28:43 2008
@@ -26,6 +26,8 @@
 
 #include <glib-object.h>
 
+#include "gkr-pkix-types.h"
+
 #include <gcrypt.h>
 #include <libtasn1.h>
 
@@ -34,18 +36,6 @@
 
 G_BEGIN_DECLS
 
-typedef enum _GkrParseResult {
-	GKR_PARSE_FAILURE = -1,
-	GKR_PARSE_UNRECOGNIZED = 0,
-	GKR_PARSE_SUCCESS = 1
-} GkrParseResult;
-
-typedef enum _GkrParsedType {
-	GKR_PARSED_UNKNOWN = 0,
-	GKR_PARSED_PRIVATE_KEY = 1,
-	GKR_PARSED_CERTIFICATE = 2
-} GkrParsedType;
-
 #define GKR_PKIX_PARSE_ERROR             (gkr_pkix_parser_get_error_domain ())
 
 #define GKR_TYPE_PKIX_PARSER             (gkr_pkix_parser_get_type ())
@@ -67,21 +57,21 @@
 
 	/* When an object is not fully parsed because of restrictions */	
 	gboolean (*parsed_partial) (GkrPkixParser *parser, GQuark location, 
-	                            gkrconstunique unique, GkrParsedType type);
+	                            gkrconstunique unique, GQuark type);
 
 	/* When an ASN.1 type object is parsed */
 	gboolean (*parsed_asn1) (GkrPkixParser *parser, GQuark location, 
-	                         gkrconstunique unique, GkrParsedType type,
+	                         gkrconstunique unique, GQuark type,
 	                         ASN1_TYPE asn1);
 
 	/* When a gcrypt sexp is parsed */
 	gboolean (*parsed_sexp) (GkrPkixParser *parser, GQuark location, 
-	                         gkrconstunique unique, GkrParsedType type,
+	                         gkrconstunique unique, GQuark type,
 	                         gcry_sexp_t sexp);
 	
 	/* A callback for each password needed */
 	gchar* (*ask_password) (GkrPkixParser *parser, GQuark location, 
-	                        gkrconstunique unique, GkrParsedType type,
+	                        gkrconstunique unique, GQuark type,
 				const gchar *orig_label, guint failed);
 };
 
@@ -91,11 +81,7 @@
 
 GkrPkixParser*      gkr_pkix_parser_new                     (void);
 
-const gchar*        gkr_pkix_parsed_type_to_string          (GkrParsedType type);
-
-const gchar*        gkr_pkix_parsed_type_to_display         (GkrParsedType type);
-
-GkrParsedType       gkr_pkix_parsed_type_from_string        (const gchar *string);
+const gchar*        gkr_pkix_parsed_type_to_display         (GQuark type);
 
 gboolean            gkr_pkix_parser_parse                   (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data, 
@@ -104,48 +90,48 @@
 gboolean            gkr_pkix_parser_parse_location          (GkrPkixParser *parser, GQuark loc, 
                                                              GError **err);
 
-GkrParseResult      gkr_pkix_parser_der                     (GkrPkixParser *parser, GQuark loc, 
+GkrPkixResult       gkr_pkix_parser_der                     (GkrPkixParser *parser, GQuark loc, 
                                                              const guchar *data, gsize n_data);
                                                              
 /* Private keys ------------------------------------------------------------- */
 
-GkrParseResult      gkr_pkix_parser_der_private_key         (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_private_key         (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data);
 
-GkrParseResult      gkr_pkix_parser_der_pkcs8               (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_pkcs8               (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data); 
 
-GkrParseResult      gkr_pkix_parser_der_pkcs8_plain         (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_pkcs8_plain         (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data); 
 
-GkrParseResult      gkr_pkix_parser_der_pkcs8_encrypted     (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_pkcs8_encrypted     (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data); 
 
 /* X509 --------------------------------------------------------------------- */
 
-GkrParseResult      gkr_pkix_parser_der_certificate         (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_certificate         (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data);
 
 #ifdef FUTURE
 
-GkrParseResult      gkr_pkix_parser_der_crl                 (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_crl                 (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data,
                                                              ASN1_TYPE *crl);
 
-GkrParseResult      gkr_pkix_parser_der_pkcs10              (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_pkcs10              (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data,
                                                              ASN1_TYPE *crl);
 #endif
 
 /* Container Formats -------------------------------------------------------- */
 
-GkrParseResult      gkr_pkix_parser_pem                     (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_pem                     (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data);
 
-GkrParseResult      gkr_pkix_parser_der_pkcs12              (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_pkcs12              (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data);
 
-GkrParseResult      gkr_pkix_parser_der_pkcs7               (GkrPkixParser *parser, GQuark loc,
+GkrPkixResult       gkr_pkix_parser_der_pkcs7               (GkrPkixParser *parser, GQuark loc,
                                                              const guchar *data, gsize n_data);
 
 G_END_DECLS

Added: trunk/pkix/gkr-pkix-serialize.c
==============================================================================
--- (empty file)
+++ trunk/pkix/gkr-pkix-serialize.c	Sun Feb  3 01:28:43 2008
@@ -0,0 +1,297 @@
+
+#include "config.h"
+
+#include "gkr-pkix-asn1.h"
+#include "gkr-pkix-der.h"
+#include "gkr-pkix-serialize.h"
+#include "gkr-pkix-types.h"
+
+#include "common/gkr-crypto.h"
+#include "common/gkr-location.h"
+#include "common/gkr-secure-memory.h"
+
+#include <glib/gi18n.h>
+
+#include <stdlib.h>
+
+/* -----------------------------------------------------------------------------
+ * QUARK DEFINITIONS
+ */
+
+static GQuark OID_PKIX1_RSA;
+static GQuark OID_PKIX1_DSA;
+static GQuark OID_PKCS12_PBE_3DES_SHA1;
+
+static void
+init_quarks (void)
+{
+	#define QUARK(name, value) \
+		name = g_quark_from_static_string(value)
+ 
+	QUARK (OID_PKIX1_RSA, "1.2.840.113549.1.1.1");
+	QUARK (OID_PKIX1_DSA, "1.2.840.10040.4.1");
+	QUARK (OID_PKCS12_PBE_3DES_SHA1, "1.2.840.113549.1.12.1.3");
+	
+	#undef QUARK
+}
+
+/* ----------------------------------------------------------------------------
+ * PUBLIC FUNCTIONS
+ */
+
+gboolean
+gkr_pkix_serialize_to_location (GQuark type, gpointer what, const gchar *password, 
+                                GQuark location, GError **err)
+{
+	gboolean ret;
+	gchar *path;
+	guchar *data;
+	gsize n_data;
+	
+	data = gkr_pkix_serialize_to_data (type, what, password, &n_data);
+	g_return_val_if_fail (data, FALSE);
+	
+	path = gkr_location_to_path (location);
+	if (!path) {
+		g_free (data);
+		g_set_error (err, G_FILE_ERROR, G_FILE_ERROR_NODEV, "%s",  
+		             _("The disk or drive this file is located on is not present"));
+		return FALSE;
+	}
+	
+	ret = g_file_set_contents (path, (const gchar*)data, n_data, err);
+	g_free (path);
+	g_free (data);
+	
+	return ret;
+}
+
+guchar*
+gkr_pkix_serialize_to_data (GQuark type, gpointer what, const gchar *password, 
+                            gsize *n_data)
+{
+	if (type == GKR_PKIX_CERTIFICATE) 
+		return gkr_pkix_serialize_certificate ((ASN1_TYPE)what, n_data);
+	
+	else if (type == GKR_PKIX_PUBLIC_KEY)
+		return gkr_pkix_serialize_public_key ((gcry_sexp_t)what, n_data);
+		
+	else if (type == GKR_PKIX_PRIVATE_KEY)
+		return gkr_pkix_serialize_private_key_pkcs8 ((gcry_sexp_t)what, password, n_data);
+		
+	g_return_val_if_reached (NULL);
+}
+
+guchar*           
+gkr_pkix_serialize_certificate (ASN1_TYPE asn, gsize *n_data)
+{
+	g_return_val_if_fail (asn, NULL);
+	g_return_val_if_fail (n_data, NULL);
+	return gkr_pkix_der_write_certificate (asn, n_data);
+}
+
+guchar*
+gkr_pkix_serialize_public_key (gcry_sexp_t skey, gsize *n_data)
+{
+	g_return_val_if_fail (skey, NULL);
+	g_return_val_if_fail (n_data, NULL);
+	return gkr_pkix_der_write_public_key (skey, n_data);
+}
+
+static gcry_cipher_hd_t
+prepare_and_encode_pkcs8_cipher (ASN1_TYPE asn, const gchar *password, gsize *n_block)
+{
+	ASN1_TYPE asn1_params;
+	gcry_cipher_hd_t cih;
+	guchar salt[8];
+	gcry_error_t gcry;
+	guchar *key, *iv, *portion;
+	gsize n_key, n_portion;
+	int iterations, res;
+	
+	init_quarks ();
+
+	/* Make sure the encryption algorithm works */
+	g_return_val_if_fail (gcry_cipher_algo_info (OID_PKCS12_PBE_3DES_SHA1, 
+			                                     GCRYCTL_TEST_ALGO, NULL, 0), NULL);
+
+	/* The encryption algorithm */
+	if(!gkr_pkix_asn1_write_oid (asn, "encryptionAlgorithm.algorithm", 
+	                             OID_PKCS12_PBE_3DES_SHA1))
+		g_return_val_if_reached (NULL); 
+
+	/* Randomize some input for the password based secret */
+	iterations = 1000 + (int) (1000.0 * rand () / (RAND_MAX + 1.0));
+	gcry_create_nonce (salt, sizeof (salt));
+
+	/* Allocate space for the key and iv */
+	n_key = gcry_cipher_get_algo_keylen (GCRY_CIPHER_3DES);
+	*n_block = gcry_cipher_get_algo_blklen (GCRY_MD_SHA1);
+	g_return_val_if_fail (n_key && *n_block, NULL);
+		
+	if (!gkr_crypto_generate_symkey_pkcs12 (GCRY_CIPHER_3DES, GCRY_MD_SHA1, 
+	                                        password, salt, sizeof (salt),
+	                                        iterations, &key, &iv))
+		g_return_val_if_reached (NULL);
+
+	/* Now write out the parameters */	
+	res = asn1_create_element (gkr_pkix_asn1_get_pkix_asn1type (),
+	                           "PKIX1.pkcs-12-PbeParams", &asn1_params);
+	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+	if (!gkr_pkix_asn1_write_value (asn1_params, "salt", salt, sizeof (salt)))
+		g_return_val_if_reached (NULL);
+	if (!gkr_pkix_asn1_write_uint (asn1_params, "iterations", iterations))
+		g_return_val_if_reached (NULL);
+	portion = gkr_pkix_asn1_encode (asn1_params, "", &n_portion, NULL);
+	g_return_val_if_fail (portion, NULL); 
+	
+	if (!gkr_pkix_asn1_write_value (asn, "encryptionAlgorithm.parameters", portion, n_portion))
+		g_return_val_if_reached (NULL);
+	g_free (portion);
+	
+	/* Now make a cipher that matches what we wrote out */
+	gcry = gcry_cipher_open (&cih, GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC, 0);
+	g_return_val_if_fail (gcry == 0, NULL);
+	g_return_val_if_fail (cih, NULL);
+	
+	gcry_cipher_setiv (cih, iv, *n_block);
+	gcry_cipher_setkey (cih, key, n_key);
+	
+	gkr_secure_free (iv);
+	gkr_secure_free (key);
+	asn1_delete_structure (&asn1_params);
+	
+	return cih;
+}
+
+static guchar*
+encode_pkcs8_private_key (gcry_sexp_t skey, gsize *n_data)
+{
+	ASN1_TYPE asn;
+	int res, algorithm;
+	gboolean is_priv;
+	GQuark oid;
+	guchar *params, *key, *data;
+	gsize n_params, n_key;
+	
+	init_quarks ();
+
+	/* Parse and check that the key is for real */
+	if (!gkr_crypto_skey_parse (skey, &algorithm, &is_priv, NULL))
+		g_return_val_if_reached (NULL);
+	g_return_val_if_fail (is_priv == TRUE, NULL);
+	
+	res = asn1_create_element (gkr_pkix_asn1_get_pkix_asn1type (), 
+	                           "PKIX1.pkcs-8-PrivateKeyInfo", &asn);
+	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+	
+	/* Write out the version */
+	if (!gkr_pkix_asn1_write_uint (asn, "version", 1))
+		g_return_val_if_reached (NULL);
+	
+	/* Per algorithm differences */
+	switch (algorithm)
+	{
+	/* RSA gets encoded in a standard simple way */
+	case GCRY_PK_RSA:
+		oid = OID_PKIX1_RSA;
+		params = NULL;
+		n_params = 0;
+		key = gkr_pkix_der_write_private_key_rsa (skey, &n_key);
+		break;
+		
+	/* DSA gets incoded with the params seperate */
+	case GCRY_PK_DSA:
+		oid = OID_PKIX1_DSA;
+		key = gkr_pkix_der_write_private_key_dsa_part (skey, &n_key);
+		params = gkr_pkix_der_write_private_key_dsa_params (skey, &n_params);
+		break;
+		
+	default:
+		g_warning ("trying to serialize unsupported private key algorithm: %d", algorithm);
+		return NULL;
+	};
+	
+	/* Write out the algorithm */
+	if (!gkr_pkix_asn1_write_oid (asn, "privateKeyAlgorithm.algorithm", oid))
+		g_return_val_if_reached (NULL);
+
+	/* Write out the parameters */
+	if (!gkr_pkix_asn1_write_value (asn, "privateKeyAlgorithm.parameters", params, n_params))
+		g_return_val_if_reached (NULL);
+	gkr_secure_free (params);
+	
+	/* Write out the key portion */
+	if (!gkr_pkix_asn1_write_value (asn, "privateKey", key, n_key))
+		g_return_val_if_reached (NULL);
+	gkr_secure_free (key);
+	
+	/* Add an empty attributes field */
+	if (!gkr_pkix_asn1_write_value (asn, "attributes", NULL, 0))
+		g_return_val_if_reached (NULL);
+	
+	data = gkr_pkix_asn1_encode (asn, "", n_data, NULL);
+	g_return_val_if_fail (data, NULL); 
+	
+	asn1_delete_structure (&asn);
+	
+	return data;
+}
+
+guchar*
+gkr_pkix_serialize_private_key_pkcs8 (gcry_sexp_t skey, const gchar *password, 
+                                      gsize *n_data)
+{
+	gcry_error_t gcry;
+	gcry_cipher_hd_t cih;
+	ASN1_TYPE asn;
+	int res;
+	guchar *key, *data; 
+	gsize n_key, block = 0;
+
+	/* Encode the key in normal pkcs8 fashion */
+	key = encode_pkcs8_private_key (skey, &n_key);
+	
+	/* If no encryption then just return that */
+	if(!password || !password[0]) {
+		*n_data = n_key;
+		return key;
+	}
+	
+	res = asn1_create_element (gkr_pkix_asn1_get_pkix_asn1type (), 
+	                           "PKIX1.pkcs-8-EncryptedPrivateKeyInfo", &asn);
+	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+	
+	/* Create a and write out a cipher used for encryption */
+	cih = prepare_and_encode_pkcs8_cipher (asn, password, &block);
+	g_return_val_if_fail (cih, NULL);
+	
+	/* Pad the block of data */
+	if(block > 1) {
+		gsize pad;
+		guchar *padded;
+		
+		pad = block - (n_key % block);
+		if (pad == 0)
+			pad = block;
+		padded = g_realloc (key, n_key + pad);
+		memset (padded + n_key, pad, pad);
+		key = padded;
+		n_key += pad;
+	}
+	
+	gcry = gcry_cipher_encrypt (cih, key, n_key, NULL, 0);
+	g_return_val_if_fail (gcry == 0, NULL);
+	
+	gcry_cipher_close (cih);
+	
+	res = asn1_write_value (asn, "encryptedData", key, n_key);
+	g_return_val_if_fail (res == ASN1_SUCCESS, NULL);
+	
+	data = gkr_pkix_asn1_encode (asn, "", n_data, NULL);
+	g_return_val_if_fail (data, NULL); 
+
+	asn1_delete_structure (&asn);
+	
+	return data;
+}

Added: trunk/pkix/gkr-pkix-serialize.h
==============================================================================
--- (empty file)
+++ trunk/pkix/gkr-pkix-serialize.h	Sun Feb  3 01:28:43 2008
@@ -0,0 +1,24 @@
+#ifndef GKRPKIXSERIALIZE_H_
+#define GKRPKIXSERIALIZE_H_
+
+#include <glib.h>
+
+#include <gcrypt.h>
+#include <libtasn1.h>
+
+gboolean          gkr_pkix_serialize_to_location        (GQuark type, gpointer what, 
+                                                         const gchar *password, 
+                                                         GQuark location, GError **err);
+
+guchar*           gkr_pkix_serialize_to_data            (GQuark type, gpointer what, 
+                                                         const gchar *password, 
+                                                         gsize *n_data);
+
+guchar*           gkr_pkix_serialize_certificate        (ASN1_TYPE asn, gsize *n_data);
+
+guchar*           gkr_pkix_serialize_public_key         (gcry_sexp_t skey, gsize *n_data);
+
+guchar*           gkr_pkix_serialize_private_key_pkcs8  (gcry_sexp_t skey, const gchar *password, 
+                                                         gsize *n_data);
+
+#endif /*GKRPKIXSERIALIZE_H_*/

Added: trunk/pkix/gkr-pkix-types.h
==============================================================================
--- (empty file)
+++ trunk/pkix/gkr-pkix-types.h	Sun Feb  3 01:28:43 2008
@@ -0,0 +1,14 @@
+#ifndef GKRPKIXTYPES_H_
+#define GKRPKIXTYPES_H_
+
+typedef enum _GkrPkixResult {
+	GKR_PKIX_FAILURE = -1,
+	GKR_PKIX_UNRECOGNIZED = 0,
+	GKR_PKIX_SUCCESS = 1
+} GkrPkixResult;
+
+#define  GKR_PKIX_CERTIFICATE      (g_quark_from_static_string ("certificate"))
+#define  GKR_PKIX_PUBLIC_KEY       (g_quark_from_static_string ("public-key"))
+#define  GKR_PKIX_PRIVATE_KEY      (g_quark_from_static_string ("private-key"))
+
+#endif /*GKRPKIXTYPES_H_*/

Modified: trunk/pkix/tests/Makefile.am
==============================================================================
--- trunk/pkix/tests/Makefile.am	(original)
+++ trunk/pkix/tests/Makefile.am	Sun Feb  3 01:28:43 2008
@@ -10,6 +10,7 @@
 	unit-test-pkix-asn1.c \
 	unit-test-pkix-der.c \
 	unit-test-pkix-parser.c \
+	unit-test-pkix-serialize.c \
 	$(BUILT_SOURCES)
 
 UNIT_PROMPT = 

Added: trunk/pkix/tests/test-data/der-certificate.crt
==============================================================================
Binary file. No diff available.

Modified: trunk/pkix/tests/unit-test-pkix-der.c
==============================================================================
--- trunk/pkix/tests/unit-test-pkix-der.c	(original)
+++ trunk/pkix/tests/unit-test-pkix-der.c	Sun Feb  3 01:28:43 2008
@@ -25,6 +25,8 @@
 
 #include "run-auto-test.h"
 
+#include "common/gkr-crypto.h"
+
 #include "pkix/gkr-pkix-der.h"
 
 #include <glib.h>
@@ -47,25 +49,53 @@
  * Tests be run in the order specified here.
  */
 
-const gchar *rsadef = "(public-key (rsa" \
+const gchar *rsapub = "(public-key (rsa" \
 " (n #00AE4B381CF43F7DC24CF90827325E2FB2EB57EDDE29562DF391C8942AA8E6423410E2D3FE26381F9DE0395E74BF2D17621AE46992C72CF895F6FA5FBE98054FBF#)" \
 " (e #010001#)))";
 
-const gchar *dsadef = "(public-key (dsa" \
+const gchar *rsaprv = "(private-key (rsa" \
+" (n #00B78758D55EBFFAB61D07D0DC49B5309A6F1DA2AE51C275DFC2370959BB81AC0C39093B1C618E396161A0DECEB8768D0FFB14F197B96C3DA14190EE0F20D51315#)" \
+" (e #010001#)" \
+" (d #108BCAC5FDD35812981E6EC5957D98E2AB76E4064C47B861D27C2CC322C50792313C852B4164A035B42D261F1A09F9FFE8F477F9F78FF2EABBDA6BA875C671D7#)" \
+" (p #00C357F11B19A18C66573D25D1E466D9AB8BCDDCDFE0B2E80BD46712C4BEC18EB7#)" \
+" (q #00F0843B90A60EF7034CA4BE80414ED9497CABCC685143B388013FF989CBB0E093#)" \
+" (u #12F2555F52EB56329A991CF0404B51C68AC921AD370A797860F550415FF987BD#)))";
+
+const gchar *dsapub = "(public-key (dsa" \
 " (p #0090EC0B60735839C754EAF8F64BB03FC35398D69772BFAE540079DEA2D3A61FAFFB27630A038A01A3D0CD62A10745A574A27ECB462F4F0885B79C61BBE954A60A29668AD54BBA5C07A72FD8B1105249670B339DF2C59E64A47064EFCF0B7236C5C72CD55CEB32917430BEC9A003D4E484FBAA84D79571B38D6B5AC95BB73E3F7B#)" \
 " (q #00FA214A1385C21BFEBAADAB240A2430C607D56271#)" \
 " (g #2DE05751F5DAEE97F3D43C54595A3E94A080728F0C66C98AEBED5762F6AB155802D8359EAD1DE1EC36A459FBEEEA48E59B9E6A8CB4F5295936B3CC881A5D957C7339175E2CFFE0F30D3711E430DB6648C2EB474AA10A4A3297450531FF2C7C6951220C9D446B6B6B0F00262E1EBEB3CC861476AA518CC555C9ABF9E5F39023FC#)" \
 " (y #54734451DB79D4EEDF0BBCEBD43BB6CBB7B8584603B957080075DD318EB5B0266D4B20DC5EFF376BDFC4EA2983B1F7F02A39ED4C619ED68712729FFF3B7C696ADD1B6D748F56A4B4BEC5C4385E528423A3B88AE65E6D5500F97839E7A486255982189C3B4FA8D94338C76F0E5CAFC9A30A1ED728BB9F2091D594E3250A09EA00#)))";
 
+const gchar *dsaprv = "(private-key (dsa" \
+"  (p #0090EC0B60735839C754EAF8F64BB03FC35398D69772BFAE540079DEA2D3A61FAFFB27630A038A01A3D0CD62A10745A574A27ECB462F4F0885B79C61BBE954A60A29668AD54BBA5C07A72FD8B1105249670B339DF2C59E64A47064EFCF0B7236C5C72CD55CEB32917430BEC9A003D4E484FBAA84D79571B38D6B5AC95BB73E3F7B#)" \
+"  (q #00FA214A1385C21BFEBAADAB240A2430C607D56271#)" \
+"  (g #2DE05751F5DAEE97F3D43C54595A3E94A080728F0C66C98AEBED5762F6AB155802D8359EAD1DE1EC36A459FBEEEA48E59B9E6A8CB4F5295936B3CC881A5D957C7339175E2CFFE0F30D3711E430DB6648C2EB474AA10A4A3297450531FF2C7C6951220C9D446B6B6B0F00262E1EBEB3CC861476AA518CC555C9ABF9E5F39023FC#)" \
+"  (y #54734451DB79D4EEDF0BBCEBD43BB6CBB7B8584603B957080075DD318EB5B0266D4B20DC5EFF376BDFC4EA2983B1F7F02A39ED4C619ED68712729FFF3B7C696ADD1B6D748F56A4B4BEC5C4385E528423A3B88AE65E6D5500F97839E7A486255982189C3B4FA8D94338C76F0E5CAFC9A30A1ED728BB9F2091D594E3250A09EA00#)" \
+"  (x #00876F84F709D51108DFB0CBFA1F1C569C09C413EC#)))";
+
+static gboolean
+compare_keys (CuTest *cu, gcry_sexp_t key, gcry_sexp_t sexp)
+{
+	guchar hash1[20], hash2[20];
+	guchar *p;
+	
+	/* Now compare them */
+	p = gcry_pk_get_keygrip (key, hash1);
+	CuAssert (cu, "couldn't get key id for private key", p == hash1);
+	p = gcry_pk_get_keygrip (key, hash2);
+	CuAssert (cu, "couldn't get key id for parsed private key", p == hash2);
+
+	return memcmp (hash1, hash2, 20) == 0;
+}
+
 static void
 test_der_public (CuTest *cu, gcry_sexp_t key)
 {
-	guchar hash1[20], hash2[20];
 	guchar *data;
 	gsize n_data;
-	GkrParseResult ret;
+	GkrPkixResult ret;
 	gcry_sexp_t sexp;
-	guchar *p;
 		
 	/* Encode it */
 	data = gkr_pkix_der_write_public_key (key, &n_data);
@@ -74,16 +104,11 @@
 	
 	/* Now parse it */
 	ret = gkr_pkix_der_read_public_key (data, n_data, &sexp);
-	CuAssert (cu, "couldn't decode public key", ret == GKR_PARSE_SUCCESS);
+	CuAssert (cu, "couldn't decode public key", ret == GKR_PKIX_SUCCESS);
 	CuAssert (cu, "parsed key is empty", sexp != NULL);
 	
 	/* Now compare them */
-	p = gcry_pk_get_keygrip (key, hash1);
-	CuAssert (cu, "couldn't get key id for public key", p == hash1);
-	p = gcry_pk_get_keygrip (key, hash2);
-	CuAssert (cu, "couldn't get key id for parsed public key", p == hash2);
-
-	CuAssert (cu, "public key parsed differently", memcmp (hash1, hash2, 20) == 0); 	
+	CuAssert (cu, "key parsed differently", compare_keys (cu, key, sexp)); 	
 }
 
 void unit_test_der_rsa_public (CuTest* cu)
@@ -91,7 +116,7 @@
 	gcry_sexp_t key;
 	gcry_error_t gcry;
 	
-	gcry = gcry_sexp_sscan (&key, NULL, rsadef, strlen (rsadef));
+	gcry = gcry_sexp_sscan (&key, NULL, rsapub, strlen (rsapub));
 	g_return_if_fail (gcry == 0);
 
 	test_der_public (cu, key);	
@@ -102,8 +127,78 @@
 	gcry_sexp_t key;
 	gcry_error_t gcry;
 	
-	gcry = gcry_sexp_sscan (&key, NULL, dsadef, strlen (dsadef));
+	gcry = gcry_sexp_sscan (&key, NULL, dsapub, strlen (dsapub));
 	g_return_if_fail (gcry == 0);
 
 	test_der_public (cu, key);	
 }
+
+static void
+test_der_private (CuTest *cu, gcry_sexp_t key)
+{
+	guchar *data;
+	gsize n_data;
+	GkrPkixResult ret;
+	gcry_sexp_t sexp;
+
+	/* Encode it */
+	data = gkr_pkix_der_write_private_key (key, &n_data);
+	CuAssert (cu, "couldn't encode private key", data != NULL);
+	CuAssert (cu, "encoding is empty", n_data > 0);
+	
+	/* Now parse it */
+	ret = gkr_pkix_der_read_private_key (data, n_data, &sexp);
+	CuAssert (cu, "couldn't decode private key", ret == GKR_PKIX_SUCCESS);
+	CuAssert (cu, "parsed key is empty", sexp != NULL);
+	
+	/* Now compare them */
+	CuAssert (cu, "key parsed differently", compare_keys (cu, key, sexp)); 	
+}
+
+void unit_test_der_rsa_private (CuTest* cu)
+{
+	gcry_sexp_t key;
+	gcry_error_t gcry;
+	
+	gcry = gcry_sexp_sscan (&key, NULL, rsaprv, strlen (rsaprv));
+	g_return_if_fail (gcry == 0);
+	
+	test_der_private (cu, key);
+}
+
+void unit_test_der_dsa_private (CuTest* cu)
+{
+	gcry_sexp_t key;
+	gcry_error_t gcry;
+	
+	gcry = gcry_sexp_sscan (&key, NULL, dsaprv, strlen (dsaprv));
+	g_return_if_fail (gcry == 0);
+	
+	test_der_private (cu, key);
+}
+
+void unit_test_der_dsa_private_parts (CuTest* cu)
+{
+	guchar *params, *key;
+	gsize n_params, n_key;
+	gcry_sexp_t skey, pkey;
+	gcry_error_t gcry;
+	GkrPkixResult result;
+	
+	gcry = gcry_sexp_sscan (&skey, NULL, dsaprv, strlen (dsaprv));
+	g_return_if_fail (gcry == 0);
+	
+	/* Encode the the dsa key by parts */
+	params = gkr_pkix_der_write_private_key_dsa_params (skey, &n_params);
+	CuAssert (cu, "didn't encode dsa params", params != NULL);
+	key = gkr_pkix_der_write_private_key_dsa_part (skey, &n_key);
+	CuAssert (cu, "didn't encode dsa key", key != NULL);
+	
+	/* Parse the dsa key by parts */
+	result = gkr_pkix_der_read_private_key_dsa_parts (key, n_key, params, n_params, &pkey);
+	CuAssert (cu, "couldn't parse dsa parts", result == GKR_PKIX_SUCCESS);
+	CuAssert (cu, "parsing dsa parts resulted in null key", pkey != NULL);
+	
+	/* Now compare them */
+	CuAssert (cu, "key parsed differently", compare_keys (cu, skey, pkey)); 	
+}

Modified: trunk/pkix/tests/unit-test-pkix-parser.c
==============================================================================
--- trunk/pkix/tests/unit-test-pkix-parser.c	(original)
+++ trunk/pkix/tests/unit-test-pkix-parser.c	Sun Feb  3 01:28:43 2008
@@ -54,7 +54,7 @@
 
 static GkrPkixParser *parser = NULL;
 
-static GkrParsedType last_type_parsed = 0;
+static GQuark last_type_parsed = 0;
 static gcry_sexp_t last_sexp_parsed = NULL;
 static ASN1_TYPE last_asn1_parsed = NULL;
 static guint n_parsed = 0;
@@ -63,7 +63,7 @@
 
 static gboolean
 parsed_partial (GkrPkixParser *parser, GQuark location, gkrconstunique unique, 
-                GkrParsedType type, gpointer user_data)
+                GQuark type, gpointer user_data)
 {
 	CuTest *cu = the_cu;
 	g_assert (cu);
@@ -83,7 +83,7 @@
 
 static gboolean
 parsed_sexp (GkrPkixParser *parser, GQuark location, gkrconstunique unique, 
-             GkrParsedType type, gcry_sexp_t sexp, gpointer user_data)
+             GQuark type, gcry_sexp_t sexp, gpointer user_data)
 {
 	CuTest *cu = the_cu;
 	g_assert (cu);
@@ -105,7 +105,7 @@
 
 static gboolean
 parsed_asn1 (GkrPkixParser *parser, GQuark location, gkrconstunique unique,
-             GkrParsedType type, ASN1_TYPE asn1, gpointer user_data)
+             GQuark type, ASN1_TYPE asn1, gpointer user_data)
 {
 	CuTest *cu = the_cu;
 	g_assert (cu);
@@ -127,7 +127,7 @@
 
 static gchar*
 ask_password (GkrPkixParser *parser, GQuark loc, gkrconstunique unique, 
-              GkrParsedType type, const gchar *details, guint n_prompts, 
+              GQuark type, const gchar *details, guint n_prompts, 
               gpointer user_data) 
 {
 	CuTest *cu = the_cu;
@@ -183,7 +183,7 @@
 void unit_test_pkix_parse_der_keys (CuTest* cu)
 {
 	guchar *contents;
-	GkrParseResult result;
+	GkrPkixResult result;
 	GQuark location;
 	gsize len;
 	
@@ -194,7 +194,7 @@
 	
 	last_sexp_parsed = NULL;
 	result = gkr_pkix_parser_der_private_key (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse RSA key", result == GKR_PARSE_SUCCESS);
+	CuAssert (cu, "couldn't parse RSA key", result == GKR_PKIX_SUCCESS);
 	CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
 	
 	gkr_crypto_sexp_dump (last_sexp_parsed);
@@ -204,7 +204,7 @@
 	
 	last_sexp_parsed = NULL;
 	result = gkr_pkix_parser_der_private_key (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse DSA key", result == GKR_PARSE_SUCCESS);
+	CuAssert (cu, "couldn't parse DSA key", result == GKR_PKIX_SUCCESS);
 	CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
 	
 	gkr_crypto_sexp_dump (last_sexp_parsed);
@@ -213,7 +213,7 @@
 void unit_test_pkix_parse_der_pkcs8 (CuTest* cu)
 {
 	guchar *contents;
-	GkrParseResult result;
+	GkrPkixResult result;
 	GQuark location;
 	gsize len;
 	
@@ -224,7 +224,7 @@
 	
 	last_sexp_parsed = NULL;
 	result = gkr_pkix_parser_der_pkcs8_plain (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse PKCS8 key", result == GKR_PARSE_SUCCESS);
+	CuAssert (cu, "couldn't parse PKCS8 key", result == GKR_PKIX_SUCCESS);
 	CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
 	
 	gkr_crypto_sexp_dump (last_sexp_parsed);
@@ -234,7 +234,7 @@
 	
 	last_sexp_parsed = NULL;
 	result = gkr_pkix_parser_der_pkcs8_encrypted (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse PKCS8 key", result == GKR_PARSE_SUCCESS);
+	CuAssert (cu, "couldn't parse PKCS8 key", result == GKR_PKIX_SUCCESS);
 	CuAssert (cu, "parsed object is invalid", last_sexp_parsed != NULL);
 	
 	gkr_crypto_sexp_dump (last_sexp_parsed);	
@@ -243,7 +243,7 @@
 void unit_test_pkix_parse_pem (CuTest *cu)
 {
 	guchar *contents;
-	GkrParseResult result;
+	GkrPkixResult result;
 	GQuark location;
 	gsize len;
 	
@@ -254,7 +254,7 @@
 	
 	n_parsed = 0;
 	result = gkr_pkix_parser_pem (parser, location, contents, len);
-	CuAssert (cu, "couldn't parse PEM data", result == GKR_PARSE_SUCCESS);
+	CuAssert (cu, "couldn't parse PEM data", result == GKR_PKIX_SUCCESS);
 
 	CuAssert (cu, "invalid number of items parsed", n_parsed == 1);
 	CuAssert (cu, "invalid type of data parsed", last_sexp_parsed != NULL);

Added: trunk/pkix/tests/unit-test-pkix-serialize.c
==============================================================================
--- (empty file)
+++ trunk/pkix/tests/unit-test-pkix-serialize.c	Sun Feb  3 01:28:43 2008
@@ -0,0 +1,131 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-pkix-serialize.c: Test PKIX serialize
+
+   Copyright (C) 2008 Stefan Walter
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "config.h"
+
+#include "run-auto-test.h"
+
+#include "common/gkr-location.h"
+#include "common/gkr-crypto.h"
+#include "common/gkr-secure-memory.h"
+
+#include "pkix/gkr-pkix-der.h"
+#include "pkix/gkr-pkix-parser.h"
+#include "pkix/gkr-pkix-serialize.h"
+
+#include <glib.h>
+#include <gcrypt.h>
+#include <libtasn1.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+/* 
+ * Each test looks like (on one line):
+ *     void unit_test_xxxxx (CuTest* cu)
+ * 
+ * Each setup looks like (on one line):
+ *     void unit_setup_xxxxx (void);
+ * 
+ * Each teardown looks like (on one line):
+ *     void unit_teardown_xxxxx (void);
+ * 
+ * Tests be run in the order specified here.
+ */
+
+static void
+read_file (CuTest *cu, const gchar *filename, guchar **contents, gsize *len)
+{
+	gchar *path;
+	gboolean ret;
+	
+	path = g_build_filename (g_get_current_dir (), "test-data", filename, NULL);
+	ret = g_file_get_contents (path, (gchar**)contents, len, NULL);
+	CuAssert (cu, "couldn't read in file", ret);
+	
+	g_free (path);
+}
+
+static gchar*
+ask_password (GkrPkixParser *parser, GQuark loc, gkrconstunique unique, 
+              GQuark type, const gchar *details, guint n_prompts, 
+              gpointer user_data) 
+{
+	CuTest *cu = (CuTest*)user_data;
+	gchar *msg;
+	
+	/* Should only be asking once per location */
+	if (n_prompts > 0) {
+		msg = g_strdup_printf ("decryption didn't work for: %s", g_quark_to_string (loc));
+		CuAssert (cu, msg, FALSE);
+		return NULL;
+	}
+	
+	CuAssert (cu, "type is zero", type != 0);
+	CuAssert (cu, "details is null", details != NULL);
+	
+	g_print ("getting password 'booo' for: %s\n", details); 	
+	
+	/* All our test encrypted stuff use this password */
+	return gkr_secure_strdup ("booo");
+}
+
+void unit_test_serialize_certificate (CuTest* cu)
+{
+	ASN1_TYPE asn, parsed;
+	guchar *input, *output;
+	gsize n_input, n_output;
+	GkrPkixResult result;
+	
+	read_file (cu, "der-certificate.crt", &input, &n_input);
+	result = gkr_pkix_der_read_certificate (input, n_input, &asn);
+	CuAssert (cu, "couldn't parse certificate file", result == GKR_PKIX_SUCCESS);
+	
+	output = gkr_pkix_serialize_to_data (GKR_PKIX_CERTIFICATE, asn, "booo", &n_output);
+	
+	result = gkr_pkix_der_read_certificate (output, n_output, &parsed);
+	CuAssert (cu, "couldn't parse encoded certificate", result == GKR_PKIX_SUCCESS);
+}
+
+void unit_test_serialize_pkcs8 (CuTest* cu)
+{
+	gcry_sexp_t key;
+	guchar *input, *output;
+	gsize n_input, n_output;
+	GkrPkixParser* parser;
+	GkrPkixResult result;
+
+	read_file (cu, "der-dsa-1024.key", &input, &n_input);
+	result = gkr_pkix_der_read_private_key_dsa (input, n_input, &key);
+	CuAssert (cu, "couldn't parse key file", result == GKR_PKIX_SUCCESS);
+	
+	/* Serializes as PKCS8 */
+	output = gkr_pkix_serialize_to_data (GKR_PKIX_PRIVATE_KEY, key, "booo", &n_output);
+	
+	parser = gkr_pkix_parser_new ();
+	g_signal_connect (parser, "ask-password", G_CALLBACK (ask_password), cu);
+
+	result = gkr_pkix_parser_der_pkcs8 (parser, 0, output, n_output);
+	CuAssert (cu, "couldn't parse encrypted certificate", result == GKR_PKIX_SUCCESS);
+}

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Sun Feb  3 01:28:43 2008
@@ -7,4 +7,5 @@
 keyrings/gkr-keyring-login.c
 pk/gkr-pk-object-storage.c
 pkix/gkr-pkix-parser.c
+pkix/gkr-pkix-serialize.c
 ui/gkr-ask-tool.c



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