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