/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