libpurple/plugins/ssl/ssl-gnutls.c

branch
soc.2013.gobjectification.plugins
changeset 37158
96b5ab42da00
parent 37157
87898632ad06
parent 36257
c5445f25f90f
child 37199
dd1760ed79e9
--- a/libpurple/plugins/ssl/ssl-gnutls.c	Tue Oct 07 00:57:07 2014 +0530
+++ b/libpurple/plugins/ssl/ssl-gnutls.c	Wed Nov 26 16:01:25 2014 +0530
@@ -118,6 +118,9 @@
 static GHashTable *host_priorities = NULL;
 #endif
 
+static gchar *x509_cert_dn(PurpleCertificate *crt);
+static gchar *x509_issuer_dn(PurpleCertificate *crt);
+
 static void
 ssl_gnutls_log(int level, const char *str)
 {
@@ -1024,7 +1027,7 @@
 	crt_dat = X509_GET_GNUTLS_DATA(crt);
 	issuer_dat = X509_GET_GNUTLS_DATA(issuer);
 
-	/* First, let's check that crt.issuer is actually issuer */
+	/* Ensure crt issuer matches the name on the issuer cert. */
 	ret = gnutls_x509_crt_check_issuer(crt_dat, issuer_dat);
 	if (ret <= 0) {
 
@@ -1034,10 +1037,9 @@
 					   ret);
 		} else {
 			gchar *crt_id, *issuer_id, *crt_issuer_id;
-			crt_id = purple_certificate_get_unique_id(crt);
-			issuer_id = purple_certificate_get_unique_id(issuer);
-			crt_issuer_id =
-				purple_certificate_get_issuer_unique_id(crt);
+			crt_id = x509_cert_dn(crt);
+			issuer_id = x509_cert_dn(issuer);
+			crt_issuer_id = x509_issuer_dn(crt);
 			purple_debug_info("gnutls/x509",
 					  "Certificate %s is issued by "
 					  "%s, which does not match %s.\n",
@@ -1053,6 +1055,41 @@
 		return FALSE;
 	}
 
+	/* Check basic constraints extension (if it exists then the CA flag must
+	   be set to true, and it must exist for certs with version 3 or higher. */
+	ret = gnutls_x509_crt_get_basic_constraints(issuer_dat, NULL, NULL, NULL);
+	if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+		if (gnutls_x509_crt_get_version(issuer_dat) >= 3) {
+			/* Reject cert (no basic constraints and cert version is >= 3). */
+			gchar *issuer_id = x509_cert_dn(issuer);
+			purple_debug_info("gnutls/x509", "Rejecting cert because the "
+					"basic constraints extension is missing from issuer cert "
+					"for %s. The basic constraints extension is required on "
+					"all version 3 or higher certs (this cert is version %d).",
+					issuer_id ? issuer_id : "(null)",
+					gnutls_x509_crt_get_version(issuer_dat));
+			g_free(issuer_id);
+			return FALSE;
+		} else {
+			/* Allow cert (no basic constraints and cert version is < 3). */
+			purple_debug_info("gnutls/x509", "Basic constraint extension is "
+					"missing from issuer cert for %s. Allowing this because "
+					"the cert is version %d and the basic constraints "
+					"extension is only required for version 3 or higher "
+					"certs.", issuer_id ? issuer_id : "(null)",
+					gnutls_x509_crt_get_version(issuer_dat));
+		}
+	} else if (ret <= 0) {
+		/* Reject cert (CA flag is false in basic constraints). */
+		gchar *issuer_id = x509_cert_dn(issuer);
+		purple_debug_info("gnutls/x509", "Rejecting cert because the CA flag "
+				"is set to false in the basic constraints extension for "
+				"issuer cert %s. ret=%d\n",
+				issuer_id ? issuer_id : "(null)", ret);
+		g_free(issuer_id);
+		return FALSE;
+	}
+
 	/* Now, check the signature */
 	/* The second argument is a ptr to an array of "trusted" issuer certs,
 	   but we're only using one trusted one */
@@ -1078,8 +1115,8 @@
 		 * perfectly clear as soon as someone looks at the debug log is
 		 * generated.
 		 */
-		crt_id = purple_certificate_get_unique_id(crt);
-		issuer_id = purple_certificate_get_issuer_unique_id(crt);
+		crt_id = x509_cert_dn(crt);
+		issuer_id = x509_issuer_dn(crt);
 		purple_debug_warning("gnutls/x509",
 				"Insecure hash algorithm used by %s to sign %s\n",
 				issuer_id, crt_id);
@@ -1090,9 +1127,9 @@
 		/* Signature didn't check out, but at least
 		   there were no errors*/
 		if (!crt_id)
-			crt_id = purple_certificate_get_unique_id(crt);
+			crt_id = x509_cert_dn(crt);
 		if (!issuer_id)
-			issuer_id = purple_certificate_get_issuer_unique_id(crt);
+			issuer_id = x509_issuer_dn(crt);
 		purple_debug_error("gnutls/x509",
 				  "Bad signature from %s on %s\n",
 				  issuer_id, crt_id);
@@ -1338,8 +1375,11 @@
 	x509_times,                      /* Activation/Expiration time */
 	x509_importcerts_from_file,      /* Multiple certificates import function */
 	x509_get_der_data,               /* Binary DER data */
-
-	NULL
+	NULL,                            /* register_trusted_tls_cert */
+	NULL,                            /* verify_cert */
+	NULL,                            /* _purple_reserved1 */
+	NULL,                            /* _purple_reserved2 */
+	NULL                             /* _purple_reserved3 */
 
 };
 

mercurial