/pidgin/main: 2ca1bb194693: Update certificate API to use 64-bit...

Daniel Atallah datallah at pidgin.im
Fri Jul 12 14:20:33 EDT 2013


Changeset: 2ca1bb194693cf7302bc08d1f408427e2912f345
Author:	 Daniel Atallah <datallah at pidgin.im>
Date:	 2013-07-11 19:17 -0400
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/2ca1bb194693

Description:

Update certificate API to use 64-bit unsigned values instead of time_t.
Fixes #15586

 * The dates may display incorrectly on glib < 2.26 because we only have ctime()
   to format the value, but (at least for NSS), functionality should be correct.

diffstat:

 ChangeLog.API                                |   4 ++
 libpurple/certificate.c                      |  53 +++++++++++++++++++++++----
 libpurple/certificate.h                      |   4 +-
 libpurple/plugins/perl/common/Certificate.xs |   2 +-
 libpurple/plugins/perl/common/typemap        |   1 +
 libpurple/plugins/ssl/ssl-gnutls.c           |  18 ++++++++-
 libpurple/plugins/ssl/ssl-nss.c              |  52 +++++++-------------------
 7 files changed, 83 insertions(+), 51 deletions(-)

diffs (296 lines):

diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -132,6 +132,10 @@ version 3.0.0 (??/??/????):
 		* PurpleXfer.bytes_remaining is now a goffset
 		* PurpleXfer.bytes_sent is now a goffset
 		* PurpleXfer.size is now a goffset
+		* PurpleCertificateScheme.get_times now uses gint64 instead of
+		  time_t to represent times
+		* purple_certificate_get_times now uses gint64 instead of
+		  time_t to represent times
 
 		Removed:
 		* _GntFileType
diff --git a/libpurple/certificate.c b/libpurple/certificate.c
--- a/libpurple/certificate.c
+++ b/libpurple/certificate.c
@@ -239,7 +239,8 @@ purple_certificate_check_signature_chain
 	GList *cur;
 	PurpleCertificate *crt, *issuer;
 	gchar *uid;
-	time_t now, activation, expiration;
+	time_t now;
+	gint64 activation, expiration;
 	gboolean ret;
 
 	g_return_val_if_fail(chain, FALSE);
@@ -277,14 +278,31 @@ purple_certificate_check_signature_chain
 				purple_debug_error("certificate",
 						"...Failed to get validity times for certificate %s\n"
 						"Chain is INVALID\n", uid);
-			else if (now > expiration)
+			else if (now > expiration) {
+#if GLIB_CHECK_VERSION(2,26,0)
+				GDateTime *exp_dt = g_date_time_new_from_unix_local(expiration);
+				gchar *expir_str = g_date_time_format(exp_dt, "%c");
+				g_date_time_unref(exp_dt);
+#else
+				gchar *expir_str = g_strdup(ctime(&expiration));
+#endif
 				purple_debug_error("certificate",
 						"...Issuer %s expired at %s\nChain is INVALID\n",
-						uid, ctime(&expiration));
-			else
+						uid, expir_str);
+				g_free(expir_str);
+			} else {
+#if GLIB_CHECK_VERSION(2,26,0)
+				GDateTime *act_dt = g_date_time_new_from_unix_local(activation);
+				gchar *activ_str = g_date_time_format(act_dt, "%c");
+				g_date_time_unref(act_dt);
+#else
+				gchar *activ_str = g_strdup(ctime(&activation));
+#endif
 				purple_debug_error("certificate",
 						"...Not-yet-activated issuer %s will be valid at %s\n"
-						"Chain is INVALID\n", uid, ctime(&activation));
+						"Chain is INVALID\n", uid, activ_str);
+				g_free(activ_str);
+			}
 
 			if (failing)
 				*failing = crt;
@@ -439,7 +457,7 @@ purple_certificate_check_subject_name(Pu
 }
 
 gboolean
-purple_certificate_get_times(PurpleCertificate *crt, time_t *activation, time_t *expiration)
+purple_certificate_get_times(PurpleCertificate *crt, gint64 *activation, gint64 *expiration)
 {
 	PurpleCertificateScheme *scheme;
 
@@ -1664,7 +1682,8 @@ x509_tls_cached_start_verify(PurpleCerti
 {
 	const gchar *tls_peers_name = "tls_peers"; /* Name of local cache */
 	PurpleCertificatePool *tls_peers;
-	time_t now, activation, expiration;
+	time_t now;
+	gint64 activation, expiration;
 	PurpleCertificateVerificationStatus flags = PURPLE_CERTIFICATE_VALID;
 	gboolean ret;
 
@@ -1687,15 +1706,31 @@ x509_tls_cached_start_verify(PurpleCerti
 				"Failed to get validity times for certificate %s\n",
 				vrq->subject_name);
 	} else if (now > expiration) {
+#if GLIB_CHECK_VERSION(2,26,0)
+		GDateTime *exp_dt = g_date_time_new_from_unix_local(expiration);
+		gchar *expir_str = g_date_time_format(exp_dt, "%c");
+		g_date_time_unref(exp_dt);
+#else
+		gchar *expir_str = g_strdup(ctime(&expiration));
+#endif
 		flags |= PURPLE_CERTIFICATE_EXPIRED;
 		purple_debug_error("certificate/x509/tls_cached",
 				"Certificate %s expired at %s\n",
-				vrq->subject_name, ctime(&expiration));
+				vrq->subject_name, expir_str);
+		g_free(expir_str);
 	} else if (now < activation) {
+#if GLIB_CHECK_VERSION(2,26,0)
+		GDateTime *act_dt = g_date_time_new_from_unix_local(activation);
+		gchar *activ_str = g_date_time_format(act_dt, "%c");
+		g_date_time_unref(act_dt);
+#else
+		gchar *activ_str = g_strdup(ctime(&activation));
+#endif
 		flags |= PURPLE_CERTIFICATE_NOT_ACTIVATED;
 		purple_debug_error("certificate/x509/tls_cached",
 				"Certificate %s is not yet valid, will be at %s\n",
-				vrq->subject_name, ctime(&activation));
+				vrq->subject_name, activ_str);
+		g_free(activ_str);
 	}
 
 	tls_peers = purple_certificate_find_pool(x509_tls_cached.scheme_name,tls_peers_name);
diff --git a/libpurple/certificate.h b/libpurple/certificate.h
--- a/libpurple/certificate.h
+++ b/libpurple/certificate.h
@@ -283,7 +283,7 @@ struct _PurpleCertificateScheme
 	gboolean (* check_subject_name)(PurpleCertificate *crt, const gchar *name);
 
 	/** Retrieve the certificate activation/expiration times */
-	gboolean (* get_times)(PurpleCertificate *crt, time_t *activation, time_t *expiration);
+	gboolean (* get_times)(PurpleCertificate *crt, gint64 *activation, gint64 *expiration);
 
 	/** Imports certificates from a file
 	 *
@@ -613,7 +613,7 @@ purple_certificate_check_subject_name(Pu
  * @return TRUE if the requested values were obtained, otherwise FALSE.
  */
 gboolean
-purple_certificate_get_times(PurpleCertificate *crt, time_t *activation, time_t *expiration);
+purple_certificate_get_times(PurpleCertificate *crt, gint64 *activation, gint64 *expiration);
 
 /**
  * Retrieves the certificate data in DER form.
diff --git a/libpurple/plugins/perl/common/Certificate.xs b/libpurple/plugins/perl/common/Certificate.xs
--- a/libpurple/plugins/perl/common/Certificate.xs
+++ b/libpurple/plugins/perl/common/Certificate.xs
@@ -157,7 +157,7 @@ purple_certificate_verify_complete(vrq, 
 	Purple::Certificate::VerificationStatus st
 
 gboolean
-purple_certificate_get_times(crt, OUTLIST time_t activation, OUTLIST time_t expiration)
+purple_certificate_get_times(crt, OUTLIST gint64 activation, OUTLIST gint64 expiration)
 	Purple::Certificate crt
 	PROTOTYPE: $
 
diff --git a/libpurple/plugins/perl/common/typemap b/libpurple/plugins/perl/common/typemap
--- a/libpurple/plugins/perl/common/typemap
+++ b/libpurple/plugins/perl/common/typemap
@@ -1,6 +1,7 @@
 TYPEMAP
 guint					T_IV
 gint					T_IV
+gint64					T_IV
 const gint *				T_PTR
 const guint *				T_PTR
 const guint8 *				T_PTR
diff --git a/libpurple/plugins/ssl/ssl-gnutls.c b/libpurple/plugins/ssl/ssl-gnutls.c
--- a/libpurple/plugins/ssl/ssl-gnutls.c
+++ b/libpurple/plugins/ssl/ssl-gnutls.c
@@ -1116,7 +1116,7 @@ x509_check_name (PurpleCertificate *crt,
 }
 
 static gboolean
-x509_times (PurpleCertificate *crt, time_t *activation, time_t *expiration)
+x509_times (PurpleCertificate *crt, gint64 *activation, gint64 *expiration)
 {
 	gnutls_x509_crt_t crt_dat;
 	/* GnuTLS time functions return this on error */
@@ -1179,9 +1179,12 @@ x509_display_string(PurpleCertificate *c
 	gchar *sha_asc;
 	GByteArray *sha_bin;
 	gchar *cn;
-	time_t activation, expiration;
+	gint64 activation, expiration;
 	gchar *activ_str, *expir_str;
 	gchar *text;
+#if GLIB_CHECK_VERSION(2,26,0)
+	GDateTime *act_dt, *exp_dt;
+#endif
 
 	/* Pull out the SHA1 checksum */
 	sha_bin = x509_sha1sum(crt);
@@ -1199,8 +1202,19 @@ x509_display_string(PurpleCertificate *c
 				   "Failed to get certificate times!\n");
 		activation = expiration = 0;
 	}
+
+#if GLIB_CHECK_VERSION(2,26,0)
+	act_dt = g_date_time_new_from_unix_local(activation);
+	activ_str = g_date_time_format(act_dt, "%c");
+	g_date_time_unref(act_dt);
+
+	exp_dt = g_date_time_new_from_unix_local(expiration);
+	expir_str = g_date_time_format(exp_dt, "%c");
+	g_date_time_unref(exp_dt);
+#else
 	activ_str = g_strdup(ctime(&activation));
 	expir_str = g_strdup(ctime(&expiration));
+#endif
 
 	/* Make messages */
 	text = g_strdup_printf(_("Common name: %s\n\n"
diff --git a/libpurple/plugins/ssl/ssl-nss.c b/libpurple/plugins/ssl/ssl-nss.c
--- a/libpurple/plugins/ssl/ssl-nss.c
+++ b/libpurple/plugins/ssl/ssl-nss.c
@@ -897,7 +897,7 @@ x509_check_name (PurpleCertificate *crt,
 }
 
 static gboolean
-x509_times (PurpleCertificate *crt, time_t *activation, time_t *expiration)
+x509_times (PurpleCertificate *crt, gint64 *activation, gint64 *expiration)
 {
 	CERTCertificate *crt_dat;
 	PRTime nss_activ, nss_expir;
@@ -923,44 +923,9 @@ x509_times (PurpleCertificate *crt, time
 
 	if (activation) {
 		*activation = nss_activ;
-#if SIZEOF_TIME_T == 4
-		/** Hack to deal with dates past the 32-bit barrier.
-		    Handling is different for signed vs unsigned 32-bit types.
-		 */
-		if (*activation != nss_activ) {
-		       	if (nss_activ < 0) {
-				purple_debug_warning("nss",
-					"Setting Activation Date to epoch to handle pre-epoch value\n");
-				*activation = 0;
-			} else {
-				purple_debug_error("nss",
-					"Activation date past 32-bit barrier, forcing invalidity\n");
-				return FALSE;
-			}
-		}
-#endif
 	}
 	if (expiration) {
 		*expiration = nss_expir;
-#if SIZEOF_TIME_T == 4
-		if (*expiration != nss_expir) {
-			if (*expiration < nss_expir) {
-				if (*expiration < 0) {
-					purple_debug_warning("nss",
-						"Setting Expiration Date to 32-bit signed max\n");
-					*expiration = PR_INT32_MAX;
-				} else {
-					purple_debug_warning("nss",
-						"Setting Expiration Date to 32-bit unsigned max\n");
-					*expiration = PR_UINT32_MAX;
-				}
-			} else {
-				purple_debug_error("nss",
-					"Expiration date prior to unix epoch, forcing invalidity\n");
-				return FALSE;
-			}
-		}
-#endif
 	}
 
 	return TRUE;
@@ -995,9 +960,12 @@ x509_display_string(PurpleCertificate *c
 	gchar *sha_asc;
 	GByteArray *sha_bin;
 	gchar *cn;
-	time_t activation, expiration;
+	gint64 activation, expiration;
 	gchar *activ_str, *expir_str;
 	gchar *text;
+#if GLIB_CHECK_VERSION(2,26,0)
+	GDateTime *act_dt, *exp_dt;
+#endif
 
 	/* Pull out the SHA1 checksum */
 	sha_bin = x509_sha1sum(crt);
@@ -1015,8 +983,18 @@ x509_display_string(PurpleCertificate *c
 				   "Failed to get certificate times!\n");
 		activation = expiration = 0;
 	}
+#if GLIB_CHECK_VERSION(2,26,0)
+	act_dt = g_date_time_new_from_unix_local(expiration);
+	activ_str = g_date_time_format(act_dt, "%c");
+	g_date_time_unref(act_dt);
+
+	exp_dt = g_date_time_new_from_unix_local(activation);
+	expir_str = g_date_time_format(exp_dt, "%c");
+	g_date_time_unref(exp_dt);
+#else
 	activ_str = g_strdup(ctime(&activation));
 	expir_str = g_strdup(ctime(&expiration));
+#endif
 
 	/* Make messages */
 	text = g_strdup_printf(_("Common name: %s\n\n"



More information about the Commits mailing list