/soc/2015/mmcc/rand: b7dd584225be: Initial addition of a randomn...

Michael McConville <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: b7dd584225bed9a28e210d9a2907778662036511
Author:	 Michael McConville <[email protected]>
Date:	 2015-08-14 18:34 -0400
Branch:	 default
URL: https://hg.pidgin.im/soc/2015/mmcc/rand/rev/b7dd584225be

Description:

Initial addition of a randomness API. The next steps are:

 * make the /dev/urandrom read logic a little less fail-happy
 * sweep through the tree, replacing all creative randomness methods

Optionally, we can add libgcrypt support for those without SSL libraries, and
(more optionally) arc4random(), getrandom() et al. support for kernels with
randomness syscalls.

diffstat:

 libpurple/plugins/ssl/ssl-gnutls.c  |   8 ++++++++
 libpurple/plugins/ssl/ssl-nss.c     |   7 +++++++
 libpurple/protocols/jabber/jabber.c |   5 ++++-
 libpurple/sslconn.c                 |   8 ++++++++
 libpurple/sslconn.h                 |  22 +++++++++++++++++++++-
 libpurple/util.c                    |  32 ++++++++++++++++++++++++++++++++
 libpurple/util.h                    |  17 +++++++++++++++++
 7 files changed, 97 insertions(+), 2 deletions(-)

diffs (211 lines):

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
@@ -31,6 +31,7 @@
 
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
+#include <gnutls/crypto.h>
 
 typedef struct
 {
@@ -1367,6 +1368,12 @@ static PurpleCertificateScheme x509_gnut
 
 };
 
+static int
+ssl_gnutls_rand_bytes(void *buf, size_t len)
+{
+	return gnutls_rnd(GNUTLS_RND_RANDOM, buf, len);
+}
+
 static PurpleSslOps ssl_ops =
 {
 	ssl_gnutls_init,
@@ -1376,6 +1383,7 @@ static PurpleSslOps ssl_ops =
 	ssl_gnutls_read,
 	ssl_gnutls_write,
 	ssl_gnutls_get_peer_certificates,
+	ssl_gnutls_rand_bytes,
 
 	/* padding */
 	NULL,
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
@@ -1208,6 +1208,12 @@ static PurpleCertificateScheme x509_nss 
 	NULL
 };
 
+static int
+ssl_nss_rand_bytes(void *buf, size_t len)
+{
+	return (int)PK11_GenerateRandom(buf, len);
+}
+
 static PurpleSslOps ssl_ops =
 {
 	ssl_nss_init,
@@ -1217,6 +1223,7 @@ static PurpleSslOps ssl_ops =
 	ssl_nss_read,
 	ssl_nss_write,
 	ssl_nss_peer_certs,
+	ssl_nss_rand_bytes,
 
 	/* padding */
 	NULL,
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -659,11 +659,14 @@ jabber_recv_cb_ssl(gpointer data, Purple
 {
 	PurpleConnection *gc = data;
 	JabberStream *js = purple_connection_get_protocol_data(gc);
-	int len;
+	int len, x, err;
 	static char buf[4096];
 
 	PURPLE_ASSERT_CONNECTION_IS_VALID(gc);
 
+	err = purple_util_random((void*)&x, sizeof(int));
+	purple_debug_error("MIKE", "err: %d - data: %x", err, x);
+
 	while((len = purple_ssl_read(gsc, buf, sizeof(buf) - 1)) > 0) {
 		purple_connection_update_last_received(gc);
 		buf[len] = '\0';
diff --git a/libpurple/sslconn.c b/libpurple/sslconn.c
--- a/libpurple/sslconn.c
+++ b/libpurple/sslconn.c
@@ -293,6 +293,14 @@ purple_ssl_get_peer_certificates(PurpleS
 	return (ops->get_peer_certificates)(gsc);
 }
 
+int
+purple_ssl_rand_bytes(void *buf, size_t len)
+{
+	PurpleSslOps *ops;
+	ops = purple_ssl_get_ops();
+	return (ops->rand_bytes)(buf, len);
+}
+
 void
 purple_ssl_set_ops(PurpleSslOps *ops)
 {
diff --git a/libpurple/sslconn.h b/libpurple/sslconn.h
--- a/libpurple/sslconn.h
+++ b/libpurple/sslconn.h
@@ -118,6 +118,11 @@ struct _PurpleSslConnection
  *                         <sbr/>@gsc:    Connection context
  *                         <sbr/>Returns: A newly allocated list containing the
  *                                        certificates the peer provided.
+ * @rand_bytes: Writes quality random data.
+ *         See purple_ssl_write().
+ *         <sbr/>@buf:    Data buffer to write data to
+ *         <sbr/>@len:    Number of bytes to write to the buffer
+ *         <sbr/>Returns: Zero on success, non-zero on error
  *
  * SSL implementation operations structure.
  *
@@ -133,10 +138,10 @@ struct _PurpleSslOps
 	void (*close)(PurpleSslConnection *gsc);
 	size_t (*read)(PurpleSslConnection *gsc, void *data, size_t len);
 	size_t (*write)(PurpleSslConnection *gsc, const void *data, size_t len);
-
 	/* TODO Decide whether the ordering of certificates in this list can be
 	        guaranteed. */
 	GList * (* get_peer_certificates)(PurpleSslConnection * gsc);
+	int (*rand_bytes)(void *buf, size_t len);
 
 	/*< private >*/
 	void (*_purple_reserved1)(void);
@@ -304,6 +309,21 @@ size_t purple_ssl_write(PurpleSslConnect
 GList * purple_ssl_get_peer_certificates(PurpleSslConnection *gsc);
 
 /**************************************************************************/
+/* Random data API                                                        */
+/**************************************************************************/
+
+/**
+ * purple_ssl_get_rand_bytes:
+ * @buf:    Data buffer to write data to
+ * @len:    Number of bytes to write to the buffer
+ *
+ * Writes quality random data.
+ *
+ * Returns: Zero on success, non-zero on error.
+ */
+int purple_ssl_rand_bytes(void *buf, size_t len);
+
+/**************************************************************************/
 /* Subsystem API                                                          */
 /**************************************************************************/
 
diff --git a/libpurple/util.c b/libpurple/util.c
--- a/libpurple/util.c
+++ b/libpurple/util.c
@@ -4988,6 +4988,38 @@ int
 	return ret;
 }
 
+int
+purple_util_random(void *buf, size_t len)
+{
+	int fd;
+	ssize_t res;
+	PurpleSslOps *ops = purple_ssl_get_ops();
+
+	/* use SSL API if possible... */
+	if (ops && ops->rand_bytes) {
+		return (ops->rand_bytes)(buf, len);
+	/* ...otherwise, fall back to /dev/urandom */
+	} else {
+		fd = open("/dev/urandom", O_RDONLY);
+		if (fd < 0) {
+			purple_debug_error("purple_random",
+					"could not open /dev/urandom: %s", g_strerror(errno));
+			return 1;
+		}
+		res = read(fd, buf, len);
+		if (res < 0) {
+			purple_debug_error("purple_random",
+					"/dev/urandom read failed: %s", g_strerror(errno));
+			return 1;
+		/* redundant condition to guard against overflow on cast */
+		} else if (res >= 0 && (size_t)res != len) {
+			purple_debug_error("purple_random", "/dev/urandom read returned too little data");
+			return 1;
+		}
+		return 0;
+	}
+}
+
 #if 0
 
 /* Temporarily removed - re-add this when you need ini file support. */
diff --git a/libpurple/util.h b/libpurple/util.h
--- a/libpurple/util.h
+++ b/libpurple/util.h
@@ -1610,6 +1610,23 @@ gchar *purple_http_digest_calculate_resp
 		const gchar *nonce_count, const gchar *client_nonce,
 		const gchar *session_key);
 
+
+/**************************************************************************/
+/* Randomness Functions                                                   */
+/**************************************************************************/
+
+/**
+ * purple_util_random:
+ * @buf:  The buffer to write to
+ * @len:  The number of bytes to write
+ *
+ * Writes quality random data to a buffer. Safe for cryptographic use.
+ * All random data used should be obtained from this function!
+ *
+ * Returns:  Zero on success, non-zero on failure.
+ */
+int purple_util_random(void *buf, size_t len);
+
 G_END_DECLS
 
 #endif /* _PURPLE_UTIL_H_ */

_______________________________________________
Commits mailing list
[email protected]
https://pidgin.im/cgi-bin/mailman/listinfo/commits
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.