From 16688474094b26c6d89c289a49c97b195e8e05bd Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Sat, 1 Apr 2017 08:47:50 +0200 Subject: [PATCH] Add support for random.org as a CSPRNG --- .travis.yml | 2 +- configure.ac | 3 + src/libsodium/Makefile.am | 5 +- src/libsodium/include/Makefile.am | 1 + src/libsodium/include/sodium.h | 1 + .../include/sodium/randombytes_randomorg.h | 19 ++++ .../randomorg/randombytes_randomorg.c | 103 ++++++++++++++++++ 7 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 src/libsodium/include/sodium/randombytes_randomorg.h create mode 100644 src/libsodium/randombytes/randomorg/randombytes_randomorg.c diff --git a/.travis.yml b/.travis.yml index 04acffb1..aa78406a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,7 @@ script: - make distclean > /dev/null - ./configure --disable-dependency-tracking --enable-minimal - make distcheck - - ( echo '#include ' ; echo 'int main(void) { return sodium_init(); }' ) > /tmp/main.c && gcc -Isrc/libsodium/include -Isrc/libsodium/include/sodium $(find src -name '*.c' -o -name '*.S') /tmp/main.c + - ( echo '#include ' ; echo 'int main(void) { return sodium_init(); }' ) > /tmp/main.c && gcc -Isrc/libsodium/include -Isrc/libsodium/include/sodium $(find src -name '*.c' -o -name '*.S') /tmp/main.c -lcurl env: global: diff --git a/configure.ac b/configure.ac index 027a075f..09ba18a0 100644 --- a/configure.ac +++ b/configure.ac @@ -700,6 +700,9 @@ AM_CONDITIONAL([EMSCRIPTEN], [test "x$EMSCRIPTEN" != "x"]) AM_CONDITIONAL([NATIVECLIENT], [test "x$NATIVECLIENT" != "x"]) +LIBCURL_CHECK_CONFIG([yes], [], [], + [AC_MSG_ERROR([[Libcurl header files not found, install libcurl-dev]])]) + AC_DEFINE([CONFIGURED], [1], [the build system was properly configured]) dnl Libtool. diff --git a/src/libsodium/Makefile.am b/src/libsodium/Makefile.am index 1539d184..6b5805aa 100644 --- a/src/libsodium/Makefile.am +++ b/src/libsodium/Makefile.am @@ -99,7 +99,8 @@ libsodium_la_SOURCES = \ if !EMSCRIPTEN libsodium_la_SOURCES += \ - randombytes/salsa20/randombytes_salsa20_random.c + randombytes/salsa20/randombytes_salsa20_random.c \ + randombytes/randomorg/randombytes_randomorg.c if NATIVECLIENT libsodium_la_SOURCES += \ @@ -183,12 +184,14 @@ endif libsodium_la_LDFLAGS = \ $(AM_LDFLAGS) \ + @LIBCURL@ \ -export-dynamic \ -no-undefined \ $(LIBTOOL_EXTRA_FLAGS) libsodium_la_CPPFLAGS = \ $(LTDLINCL) \ + @LIBCURL_CPPFLAGS@ \ -I$(srcdir)/include/sodium \ -I$(builddir)/include/sodium diff --git a/src/libsodium/include/Makefile.am b/src/libsodium/include/Makefile.am index eb75f15d..ee516361 100644 --- a/src/libsodium/include/Makefile.am +++ b/src/libsodium/include/Makefile.am @@ -53,6 +53,7 @@ SODIUM_EXPORT = \ sodium/crypto_verify_64.h \ sodium/export.h \ sodium/randombytes.h \ + sodium/randombytes_randomorg.h \ sodium/randombytes_salsa20_random.h \ sodium/randombytes_sysrandom.h \ sodium/runtime.h \ diff --git a/src/libsodium/include/sodium.h b/src/libsodium/include/sodium.h index d0bb25c8..13b572aa 100644 --- a/src/libsodium/include/sodium.h +++ b/src/libsodium/include/sodium.h @@ -51,6 +51,7 @@ #ifdef __native_client__ # include "sodium/randombytes_nativeclient.h" #endif +#include "sodium/randombytes_randomorg.h" #include "sodium/randombytes_salsa20_random.h" #include "sodium/randombytes_sysrandom.h" #include "sodium/runtime.h" diff --git a/src/libsodium/include/sodium/randombytes_randomorg.h b/src/libsodium/include/sodium/randombytes_randomorg.h new file mode 100644 index 00000000..43fa6f44 --- /dev/null +++ b/src/libsodium/include/sodium/randombytes_randomorg.h @@ -0,0 +1,19 @@ + +#ifndef randombytes_randomorg_H +#define randombytes_randomorg_H + +#include "export.h" +#include "randombytes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +SODIUM_EXPORT +extern struct randombytes_implementation randombytes_randomorg_implementation; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/libsodium/randombytes/randomorg/randombytes_randomorg.c b/src/libsodium/randombytes/randomorg/randombytes_randomorg.c new file mode 100644 index 00000000..9d607e09 --- /dev/null +++ b/src/libsodium/randombytes/randomorg/randombytes_randomorg.c @@ -0,0 +1,103 @@ + +#include +#include +#include +#include + +#include "randombytes.h" +#include "randombytes_randomorg.h" +#include "utils.h" + +typedef struct dynbuf { + char *ptr; + size_t len; +} dynbuf; + +static size_t +writefunc(void *ptr, size_t size, size_t nmemb, dynbuf *db) +{ + size_t new_len; + + new_len = db->len + size * nmemb; + if (new_len < db->len) { /* might work */ + abort(); + } + db->ptr = (char *) realloc(db->ptr, new_len + 1); + if (db->ptr == NULL) { + abort(); + } + memcpy(db->ptr + db->len, ptr, size * nmemb); + db->ptr[new_len] = 0; + db->len = new_len; + + return size * nmemb; +} + +static void +randombytes_randomorg_buf(void * const buf, const size_t size) +{ + char url[512]; + dynbuf db; + CURL *curl; + CURLcode res; + + db.len = 0; + if ((db.ptr = (char *) malloc(1)) == NULL) { + abort(); + } + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + if (curl == NULL) { + memset(buf, 0, size); /* Be robust to network failures */ + return; + } + snprintf(url, sizeof url, + "https://www.random.org/integers/?num=%llu&min=0&max=255&col=1&base=10&format=plain&rnd=new", + (unsigned long long) size); + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writefunc); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &db); + res = curl_easy_perform(curl); + if (res == CURLE_OK) { + char *p = db.ptr; + char *q; + size_t i = 0; + + while (i < size && (q = strchr(p, '\n')) != NULL) { + *q = 0; + ((unsigned char *) buf)[i++] = (unsigned char) atoi(p); + p = q + 1; + } + } + free(db.ptr); + curl_easy_cleanup(curl); + curl_global_cleanup(); +} + +static uint32_t +randombytes_randomorg(void) +{ + uint32_t r; + + randombytes_randomorg_buf(&r, sizeof r); + + return r; +} +static const char * +randombytes_randomorg_implementation_name(void) +{ + return "random.org"; +} + +struct randombytes_implementation randombytes_randomorg_implementation = { + SODIUM_C99(.implementation_name =) randombytes_randomorg_implementation_name, + SODIUM_C99(.random =) randombytes_randomorg, + SODIUM_C99(.stir =) NULL, + SODIUM_C99(.uniform =) NULL, + SODIUM_C99(.buf =) randombytes_randomorg_buf, + SODIUM_C99(.close =) NULL +};