Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use crypto safe random numbers #2738

Merged
merged 21 commits into from
Jul 30, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
@@ -610,9 +610,11 @@ janus_pp_rec_CFLAGS = \
-I$(top_builddir)/postprocessing \
$(LIBCURL_CFLAGS) \
$(POST_PROCESSING_CFLAGS) \
$(BORINGSSL_CFLAGS) \
$(NULL)

janus_pp_rec_LDADD = \
$(BORINGSSL_LIBS) \
$(POST_PROCESSING_LIBS) \
$(LIBCURL_LDFLAGS) $(LIBCURL_LIBS) \
$(NULL)
@@ -637,9 +639,11 @@ mjr2pcap_SOURCES = \
mjr2pcap_CFLAGS = \
$(AM_CFLAGS) \
$(POST_PROCESSING_CFLAGS) \
$(BORINGSSL_CFLAGS) \
$(NULL)

mjr2pcap_LDADD = \
$(BORINGSSL_LIBS) \
$(POST_PROCESSING_LIBS) \
$(POST_PROCESSING_MANUAL_LIBS) \
$(NULL)
@@ -659,9 +663,11 @@ pcap2mjr_CFLAGS = \
-I$(top_builddir)/postprocessing \
$(POST_PROCESSING_CFLAGS) \
$(PCAP_CFLAGS) \
$(BORINGSSL_CFLAGS) \
$(NULL)

pcap2mjr_LDADD = \
$(BORINGSSL_LIBS) \
$(POST_PROCESSING_LIBS) \
$(POST_PROCESSING_MANUAL_LIBS) \
$(PCAP_LIBS) \
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
@@ -954,6 +954,8 @@ AS_IF([test "x$enable_post_processing" = "xyes"],
[
glib-2.0 >= $glib_version
jansson >= $jansson_version
libssl >= $ssl_version
libcrypto
libavutil
libavcodec
libavformat
5 changes: 5 additions & 0 deletions fuzzers/rtcp_fuzzer.c
Original file line number Diff line number Diff line change
@@ -13,6 +13,11 @@ gboolean janus_log_colors = FALSE;
char *janus_log_global_prefix = NULL;
int lock_debug = 0;

/* This is to avoid linking with openSSL */
int RAND_bytes(uint8_t *key, int len) {
return 0;
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
/* Sanity Checks */
/* Max UDP payload with MTU=1500 */
5 changes: 5 additions & 0 deletions fuzzers/sdp_fuzzer.c
Original file line number Diff line number Diff line change
@@ -14,6 +14,11 @@ char *janus_log_global_prefix = NULL;
int lock_debug = 0;
int refcount_debug = 0;

/* This is to avoid linking with openSSL */
int RAND_bytes(uint8_t *key, int len) {
return 0;
}

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
/* Since we're fuzzing SDP, and that in our case SDP always comes
* from a Jansson call, this will need to be a valid string */
5 changes: 5 additions & 0 deletions janus.c
Original file line number Diff line number Diff line change
@@ -4996,6 +4996,11 @@ gint main(int argc, char *argv[])
SSL_library_init();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();
/* Check if random pool looks ok (this does not give any guarantees for later, though) */
if(RAND_status() != 1) {
JANUS_LOG(LOG_FATAL, "Random pool is not properly seeded, cannot generate random numbers\n");
exit(1);
}
/* ... and DTLS-SRTP in particular */
const char *dtls_ciphers = NULL;
item = janus_config_get(config, config_certs, janus_config_type_item, "dtls_ciphers");
5 changes: 0 additions & 5 deletions plugins/janus_nosip.c
Original file line number Diff line number Diff line change
@@ -786,11 +786,6 @@ int janus_nosip_init(janus_callbacks *callback, const char *config_path) {
}
JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);

#ifdef HAVE_SRTP_2
/* Init randomizer (for randum numbers in SRTP) */
RAND_poll();
#endif

sessions = g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify)janus_nosip_session_destroy);
messages = g_async_queue_new_full((GDestroyNotify) janus_nosip_message_free);
/* This is the callback we'll need to invoke to contact the Janus core */
5 changes: 0 additions & 5 deletions plugins/janus_sip.c
Original file line number Diff line number Diff line change
@@ -1924,11 +1924,6 @@ int janus_sip_init(janus_callbacks *callback, const char *config_path) {
}
JANUS_LOG(LOG_VERB, "Local IP set to %s\n", local_ip);

#ifdef HAVE_SRTP_2
/* Init randomizer (for randum numbers in SRTP) */
RAND_poll();
#endif

/* Setup sofia */
su_init();
if(notify_events && callback->events_is_enabled()) {
35 changes: 19 additions & 16 deletions utils.c
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@
#include <inttypes.h>

#include <zlib.h>
#include <openssl/rand.h>

#include "utils.h"
#include "debug.h"
@@ -71,23 +72,25 @@ gboolean janus_strcmp_const_time(const void *str1, const void *str2) {
}

guint32 janus_random_uint32(void) {
return g_random_int();
guint32 ret = 0;
if(RAND_bytes((void *)&ret, sizeof(ret)) != 1) {
JANUS_LOG(LOG_WARN, "Safe RAND_bytes() failed, falling back to unsafe PRNG\n");
return g_random_int();
}
return ret;
}

guint64 janus_random_uint64_full(void) {
guint64 ret = 0;
if(RAND_bytes((void *)&ret, sizeof(ret)) != 1) {
JANUS_LOG(LOG_WARN, "Safe RAND_bytes() failed, falling back to unsafe PRNG\n");
return (g_random_int() << 32) | g_random_int();
}
return ret;
}

guint64 janus_random_uint64(void) {
/*
* FIXME This needs to be improved, and use something that generates
* more strongly random stuff... using /dev/urandom is probably not
* a good idea, as we don't want to make it harder to cross compile Janus
*
* TODO Look into what libssl and/or libcrypto provide in that respect
*
* PS: JavaScript only supports integer up to 2^53, so we need to
* make sure the number is below 9007199254740992 for safety
*/
guint64 num = g_random_int() & 0x1FFFFF;
num = (num << 32) | g_random_int();
return num;
return janus_random_uint64_full() & 0x1FFFFFFFFFFFFF;
}

char *janus_random_uuid(void) {
@@ -100,8 +103,8 @@ char *janus_random_uuid(void) {
const char *template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
const char *samples = "0123456789abcdef";
union { unsigned char b[16]; uint64_t word[2]; } rnd;
rnd.word[0] = janus_random_uint64();
rnd.word[1] = janus_random_uint64();
rnd.word[0] = janus_random_uint64_full();
rnd.word[1] = janus_random_uint64_full();
/* Generate the string */
char uuid[37], *dst = uuid;
const char *p = template;
31 changes: 26 additions & 5 deletions utils.h
Original file line number Diff line number Diff line change
@@ -61,16 +61,37 @@ gboolean janus_is_true(const char *value);
gboolean janus_strcmp_const_time(const void *str1, const void *str2);

/*! \brief Helper to generate random 32-bit unsigned integers (useful for SSRCs, etc.)
* @note Currently just wraps g_random_int()
* @returns A random 32-bit unsigned integer */
* @note Warning: this will fall back to a non-cryptographically safe PRNG in case
* the crypto library RAND_bytes() call fails.
* @returns A (mostly crypto-safe) random 32-bit unsigned integer */
guint32 janus_random_uint32(void);

/*! \brief Helper to generate random 64-bit unsigned integers (useful for Janus IDs)
* @returns A random 64-bit unsigned integer */
/*! \brief Helper to generate random 64-bit unsigned integers
* @note Unlike janus_random_uint64(), which actually only generates 52 bits, this
* generates the full 64 bits. See the janus_random_uint64() docstring for details.
* Warning: this will fall back to a non-cryptographically safe PRNG in case
* the crypto library RAND_bytes() call fails.
* @returns A (mostly crypto-safe) random 52-bit unsigned integer */
guint64 janus_random_uint64_full(void);

/*! \brief Helper to generate random 52 bit unsigned integers
* @note The reason for 52 instead of 64 bits: Javascript does not have real integers,
* its builtin "number" type is a float64. Thus, only integer values up to
* <code>Number.MAX_SAFE_INTEGER == 2^53 - 1 == 9007199254740991</code>
* can be safely represented in Javascript. This method returns such numbers.
* Use this method instead of janus_random_uint64_full() whenever you generate numbers which
* might end up in Javascript (via JSON API).
* This method is called janus_random_uint64() instead of janus_random_uint52() (or similar)
* for backwards compatibility.
* Warning: this will fall back to a non-cryptographically safe PRNG in case
* the crypto library RAND_bytes() call fails.
* @returns A (mostly crypto-safe) random 64-bit unsigned integer */
guint64 janus_random_uint64(void);

/*! \brief Helper to generate random UUIDs (needed by some plugins)
* @returns A random UUID string, which must be deallocated with \c g_free */
* Warning: this will fall back to a non-cryptographically safe PRNG in case
* the crypto library RAND_bytes() call fails.
* @returns A (mostly crypto-safe) random UUID string, which must be deallocated with \c g_free */
char *janus_random_uuid(void);

/*! \brief Helper to generate an allocated copy of a guint64 number