diff libpurple/plugins/ssl/ssl-gnutls.c @ 29647:c35fd54ec64b

Implement reading multiple certificates from a single "bundle" of certificates in one file. This is most helpful for systems where system CA certs are installed as a bundle. Please test, preferably after removing any cached certificates from ~/.purple/certificates/x509/tls_peers/
author Stu Tomlinson <stu@nosnilmot.com>
date Sat, 27 Mar 2010 03:55:09 +0000
parents 401a00227615
children 9bfa52f8ee87
line wrap: on
line diff
--- a/libpurple/plugins/ssl/ssl-gnutls.c	Sat Mar 27 02:11:31 2010 +0000
+++ b/libpurple/plugins/ssl/ssl-gnutls.c	Sat Mar 27 03:55:09 2010 +0000
@@ -548,6 +548,55 @@
 	return crt;
 }
 
+/** Imports a number of PEM-formatted X.509 certificates from the specified file.
+ * @param filename Filename to import from. Format is PEM
+ *
+ * @return A newly allocated GSList of Certificate structures of the x509_gnutls scheme
+ */
+static GSList *
+x509_importcerts_from_file(const gchar * filename)
+{
+	PurpleCertificate *crt;  /* Certificate being constructed */
+	gchar *buf;        /* Used to load the raw file data */
+	gchar *begin, *end;
+	GSList *crts = NULL;
+	gsize buf_sz;      /* Size of the above */
+	gnutls_datum dt; /* Struct to pass down to GnuTLS */
+
+	purple_debug_info("gnutls",
+			  "Attempting to load X.509 certificates from %s\n",
+			  filename);
+
+	/* Next, we'll simply yank the entire contents of the file
+	   into memory */
+	/* TODO: Should I worry about very large files here? */
+	g_return_val_if_fail(
+		g_file_get_contents(filename,
+			    &buf,
+			    &buf_sz,
+			    NULL      /* No error checking for now */
+		),
+		NULL);
+
+	begin = buf;
+	while((end = strstr(begin, "-----END CERTIFICATE-----")) != NULL) {
+		end += sizeof("-----END CERTIFICATE-----")-1;
+		/* Load the datum struct */
+		dt.data = (unsigned char *) begin;
+		dt.size = (end-begin);
+
+		/* Perform the conversion; files should be in PEM format */
+		crt = x509_import_from_datum(dt, GNUTLS_X509_FMT_PEM);
+		crts = g_slist_prepend(crts, crt);
+		begin = end;
+	}
+
+	/* Cleanup */
+	g_free(buf);
+
+	return crts;
+}
+
 /**
  * Exports a PEM-formatted X.509 certificate to the specified file.
  * @param filename Filename to export to. Format will be PEM
@@ -964,10 +1013,10 @@
 	x509_common_name,                /* Subject name */
 	x509_check_name,                 /* Check subject name */
 	x509_times,                      /* Activation/Expiration time */
+	x509_importcerts_from_file,      /* Multiple certificates import function */
 
 	NULL,
 	NULL,
-	NULL,
 	NULL
 
 };