cpw.ljfisher.ssl_client_auth: 8359f5ea: Added user certificate pool for use with...

lucas.fisher at gmail.com lucas.fisher at gmail.com
Sat Apr 16 19:36:12 EDT 2011


----------------------------------------------------------------------
Revision: 8359f5eab6e07e5e3ec36dfc7489cdaccfb78499
Parent:   21fbc941e1237b596a47c6d8692907073ae5ea55
Author:   lucas.fisher at gmail.com
Date:     04/16/11 16:47:05
Branch:   im.pidgin.cpw.ljfisher.ssl_client_auth
URL: http://d.pidgin.im/viewmtn/revision/info/8359f5eab6e07e5e3ec36dfc7489cdaccfb78499

Changelog: 

Added user certificate pool for use with SSL/TLS client side cert authentication.

Changes against parent 21fbc941e1237b596a47c6d8692907073ae5ea55

  patched  libpurple/certificate.c

-------------- next part --------------
============================================================
--- libpurple/certificate.c	2fc13f5153c7ac389fe4bf692763ec8bfc9727a7
+++ libpurple/certificate.c	64b4f415067c4820bd6dc7ddf40ce692535fe361
@@ -1272,7 +1272,178 @@ static PurpleCertificatePool x509_tls_pe
 	NULL
 };
 
+/***** User's certificates and keys *****/
+/* This code is just a duplication of x509_tls_peers. We should
+   share this code.
+*/
+static PurpleCertificatePool x509_user;
 
+static gboolean
+x509_user_init(void)
+{
+	gchar *poolpath;
+	int ret;
+
+	/* Set up key cache here if it isn't already done */
+	poolpath = purple_certificate_pool_mkpath(&x509_user, NULL);
+	ret = purple_build_dir(poolpath, 0700); /* Make it this user only */
+
+	if (ret != 0)
+		purple_debug_info("certificate/user",
+				"Could not create %s.  Certificates will not be cached.\n",
+				poolpath);
+
+	g_free(poolpath);
+
+	return TRUE;
+}
+
+static gboolean
+x509_user_cert_in_pool(const gchar *id)
+{
+	gchar *keypath;
+	gboolean ret = FALSE;
+
+	g_return_val_if_fail(id, FALSE);
+
+	keypath = purple_certificate_pool_mkpath(&x509_user, id);
+
+	ret = g_file_test(keypath, G_FILE_TEST_IS_REGULAR);
+
+	g_free(keypath);
+	return ret;
+}
+
+static PurpleCertificate *
+x509_user_get_cert(const gchar *id)
+{
+	PurpleCertificateScheme *x509;
+	PurpleCertificate *crt;
+	gchar *keypath;
+
+	g_return_val_if_fail(id, NULL);
+
+	/* Is it in the pool? */
+	if ( !x509_user_cert_in_pool(id) ) {
+		return NULL;
+	}
+
+	/* Look up the X.509 scheme */
+	x509 = purple_certificate_find_scheme("x509");
+	g_return_val_if_fail(x509, NULL);
+
+	/* Okay, now find and load that key */
+	keypath = purple_certificate_pool_mkpath(&x509_user, id);
+	crt = purple_certificate_import(x509, keypath);
+
+	g_free(keypath);
+
+	return crt;
+}
+
+static gboolean
+x509_user_put_cert(const gchar *id, PurpleCertificate *crt)
+{
+	gboolean ret = FALSE;
+	gchar *keypath;
+
+	g_return_val_if_fail(crt, FALSE);
+	g_return_val_if_fail(crt->scheme, FALSE);
+	/* Make sure that this is some kind of X.509 certificate */
+	/* TODO: Perhaps just check crt->scheme->name instead? */
+	g_return_val_if_fail(crt->scheme == purple_certificate_find_scheme(x509_user.scheme_name), FALSE);
+
+	/* Work out the filename and export */
+	keypath = purple_certificate_pool_mkpath(&x509_user, id);
+	ret = purple_certificate_export(keypath, crt);
+
+	g_free(keypath);
+	return ret;
+}
+
+static gboolean
+x509_user_delete_cert(const gchar *id)
+{
+	gboolean ret = FALSE;
+	gchar *keypath;
+
+	g_return_val_if_fail(id, FALSE);
+
+	/* Is the id even in the pool? */
+	if (!x509_user_cert_in_pool(id)) {
+		purple_debug_warning("certificate/tls_peers",
+				     "Id %s wasn't in the pool\n",
+				     id);
+		return FALSE;
+	}
+
+	/* OK, so work out the keypath and delete the thing */
+	keypath = purple_certificate_pool_mkpath(&x509_user, id);
+	if ( unlink(keypath) != 0 ) {
+		purple_debug_error("certificate/tls_peers",
+				   "Unlink of %s failed!\n",
+				   keypath);
+		ret = FALSE;
+	} else {
+		ret = TRUE;
+	}
+
+	g_free(keypath);
+	return ret;
+}
+
+static GList *
+x509_user_get_idlist(void)
+{
+	GList *idlist = NULL;
+	GDir *dir;
+	const gchar *entry;
+	gchar *poolpath;
+
+	/* Get a handle on the pool directory */
+	poolpath = purple_certificate_pool_mkpath(&x509_user, NULL);
+	dir = g_dir_open(poolpath,
+			 0,     /* No flags */
+			 NULL); /* Not interested in what the error is */
+	g_free(poolpath);
+
+	g_return_val_if_fail(dir, NULL);
+
+	/* Traverse the directory listing and create an idlist */
+	while ( (entry = g_dir_read_name(dir)) != NULL ) {
+		/* Unescape the filename */
+		const char *unescaped = purple_unescape_filename(entry);
+
+		/* Copy the entry name into our list (GLib owns the original
+		   string) */
+		idlist = g_list_prepend(idlist, g_strdup(unescaped));
+	}
+
+	/* Release the directory */
+	g_dir_close(dir);
+
+	return idlist;
+}
+
+static PurpleCertificatePool x509_user = {
+	"x509",                       /* Scheme name */
+	"user",                       /* Pool name */
+	N_("SSL Peers Cache"),        /* User-friendly name */
+	NULL,                         /* Internal data */
+	x509_user_init,               /* init */
+	NULL,                         /* uninit not required */
+	x509_user_cert_in_pool,  /* Certificate exists? */
+	x509_user_get_cert,      /* Cert retriever */
+	x509_user_put_cert,      /* Cert writer */
+	x509_user_delete_cert,   /* Cert remover */
+	x509_user_get_idlist,    /* idlist retriever */
+
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 /***** A Verifier that uses the tls_peers cache and the CA pool to validate certificates *****/
 static PurpleCertificateVerifier x509_tls_cached;
 
@@ -1848,6 +2019,7 @@ purple_certificate_init(void)
 	purple_certificate_register_verifier(&x509_singleuse);
 	purple_certificate_register_pool(&x509_ca);
 	purple_certificate_register_pool(&x509_tls_peers);
+	purple_certificate_register_pool(&x509_user);
 	purple_certificate_register_verifier(&x509_tls_cached);
 }
 


More information about the Commits mailing list