changeset 18941:425f494bd1ec

- CertificateVerifier register/unregister/find - certificate_verify added, probably will change - struct Verifier: start_verification added
author William Ehlhardt <williamehlhardt@gmail.com>
date Fri, 22 Jun 2007 23:30:26 +0000
parents 5fa287322a82
children 02102eccc4be
files libpurple/certificate.c libpurple/certificate.h
diffstat 2 files changed, 143 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/certificate.c	Fri Jun 22 20:49:32 2007 +0000
+++ b/libpurple/certificate.c	Fri Jun 22 23:30:26 2007 +0000
@@ -33,6 +33,35 @@
 
 /** List holding pointers to all registered certificate schemes */
 static GList *cert_schemes = NULL;
+/** List of registered Verifiers */
+static GList *cert_verifiers = NULL;
+
+void
+purple_certificate_verify (PurpleCertificateVerificationRequest *vrq,
+			   gchar *scheme_name, gchar *ver_name,
+			   gchar *subject_name, GList *cert_chain,
+			   PurpleCertificateVerifiedCallback cb,
+			   gpointer cb_data)
+{
+	PurpleCertificateScheme *scheme;
+	PurpleCertificateVerifier *verifier;
+	
+	g_return_val_if_fail(ver_name != NULL, NULL);
+	g_return_val_if_fail(subject_name != NULL, NULL);
+	/* If you don't have a cert to check, why are you requesting that it
+	   be verified? */
+	g_return_val_if_fail(cert_chain != NULL, NULL);
+	g_return_val_if_fail(cb != NULL, NULL);
+
+	/* Locate the verifier, first */
+
+	/* Construct and fill in the request fields */
+	vrq = g_new(PurpleCertificateVerificationRequest, 1);
+	vrq->cert_chain = cert_chain;
+	vrq->cb = cb;
+	vrq->cb_data = cb_data;
+	vrq->subject_name = g_strdup(subject_name);
+}
 
 PurpleCertificateScheme *
 purple_certificate_find_scheme(const gchar *name)
@@ -88,8 +117,72 @@
 
 	/* TODO: signalling? */
 
-	/* TODO: unregister all CertificatePools for this scheme! */
+	/* TODO: unregister all CertificateVerifiers for this scheme?*/
+	/* TODO: unregister all CertificatePools for this scheme? */
+	/* Neither of the above should be necessary, though */
 	cert_schemes = g_list_remove(cert_schemes, scheme);
 
 	return TRUE;
 }
+
+PurpleCertificateVerifier *
+purple_certificate_find_verifier(const gchar *scheme_name, const gchar *ver_name)
+{
+	PurpleCertificateVerifier *vr = NULL;
+	GList *l;
+
+	g_return_val_if_fail(scheme_name, NULL);
+	g_return_val_if_fail(ver_name, NULL);
+
+	/* Traverse the list of registered verifiers and locate the
+	   one whose name matches */
+	for(l = cert_verifiers; l; l = l->next) {
+		vr = (PurpleCertificateVerifier *)(l->data);
+
+		/* Scheme and name match? */
+		if(!g_ascii_strcasecmp(vr->scheme_name, scheme_name) &&
+		   !g_ascii_strcasecmp(vr->name, ver_name))
+			return vr;
+	}
+
+	purple_debug_warning("certificate",
+			     "CertificateVerifier %s, %s requested but not found.\n",
+			     scheme_name, ver_name);
+
+	/* TODO: Signalling and such? */
+	
+	return NULL;
+}
+
+
+gboolean
+purple_certificate_register_verifier(PurpleCertificateVerifier *vr)
+{
+	g_return_val_if_fail(vr != NULL, FALSE);
+
+	/* Make sure no verifier is registered with the same scheme/name */
+	if (purple_certificate_find_verifier(vr->scheme_name, vr->name) != NULL) {
+		return FALSE;
+	}
+
+	/* Okay, we're golden. Register it. */
+	cert_verifiers = g_list_append(cert_verifiers, vr);
+
+	/* TODO: Signalling and such? */
+	return TRUE;
+}
+
+gboolean
+purple_certificate_unregister_verifier(PurpleCertificateVerifier *vr)
+{
+	if (NULL == vr) {
+		purple_debug_warning("certificate",
+				     "Attempting to unregister NULL verifier");
+	}
+
+	/* TODO: signalling? */
+
+	cert_verifiers = g_list_remove(cert_verifiers, vr);
+
+	return TRUE;
+}
--- a/libpurple/certificate.h	Fri Jun 22 20:49:32 2007 +0000
+++ b/libpurple/certificate.h	Fri Jun 22 23:30:26 2007 +0000
@@ -159,6 +159,12 @@
 
 /** A set of operations used to provide logic for verifying a Certificate's
  *  authenticity.
+ *
+ * A Verifier provider must fill out these fields, then register it using
+ * purple_certificate_register_verifier()
+ *
+ * The (scheme_name, name) value must be unique for each Verifier - you may not
+ * register more than one Verifier of the same name for each Scheme
  */
 struct _PurpleCertificateVerifier
 {
@@ -171,6 +177,18 @@
 	 * using this Verifier
 	 */
 	gchar *scheme_name;
+
+	/**
+	 * Start the verification process
+	 *
+	 * To be called from purple_certificate_verify once it has
+	 * constructed the request. This will use the information in the
+	 * given VerificationRequest to check the certificate and callback
+	 * the requester with the verification results.
+	 *
+	 * @param vrq      Request to process
+	 */
+	void (* start_verification)(PurpleCertificateVerificationRequest *vrq);
 };
 
 /** Structure for a single certificate request
@@ -182,6 +200,10 @@
 {
 	/** Reference to the verification logic used */
 	PurpleCertificateVerifier *verifier;
+	/** Reference to the scheme used.
+	 *
+	 * This is looked up from the Verifier when the Request is generated
+	 */
 
 	/**
 	 * Name to check that the certificate is issued to
@@ -239,6 +261,33 @@
 gboolean
 purple_certificate_unregister_scheme(PurpleCertificateScheme *scheme);
 
+/** Look up a registered PurpleCertificateVerifier by scheme and name
+ * @param scheme_name  Scheme name. Case insensitive.
+ * @param ver_name     The verifier name. Case insensitive.
+ * @return Pointer to the located Verifier, or NULL if it isn't found.
+ */
+PurpleCertificateVerifier *
+purple_certificate_find_verifier(const gchar *scheme_name, const gchar *ver_name);
+
+
+/**
+ * Register a CertificateVerifier with libpurple
+ *
+ * @param vr     Verifier to register.
+ * @return TRUE if register succeeded, otherwise FALSE
+ */
+gboolean
+purple_certificate_register_verifier(PurpleCertificateVerifier *vr);
+
+/**
+ * Unregister a CertificateVerifier with libpurple
+ *
+ * @param vr     Verifier to unregister.
+ * @return TRUE if register succeeded, otherwise FALSE
+ */
+gboolean
+purple_certificate_unregister_verifier(PurpleCertificateVerifier *vr);
+
 /* TODO: ADD STUFF HERE */
 
 /*@}*/