completion.c \
ConvertUTF.c \
crypto.c \
+ crypto-utils.c \
+ crypto-utils-openssl.c \
error.c \
fdlimit.c \
file.c \
clients.h \
ConvertUTF.h \
crypto.h \
+ crypto-utils.h \
completion.h \
error.h \
fdlimit.h \
#include "transmission.h"
#include "announcer.h"
#include "announcer-common.h"
-#include "crypto.h" /* tr_cryptoRandBuf () */
+#include "crypto-utils.h" /* tr_rand_buffer () */
#include "log.h"
#include "peer-io.h"
#include "peer-mgr.h" /* tr_peerMgrCompactToPex () */
tau_transaction_new (void)
{
tau_transaction_t tmp;
- tr_cryptoRandBuf (&tmp, sizeof (tau_transaction_t));
+ tr_rand_buffer (&tmp, sizeof (tau_transaction_t));
return tmp;
}
#include "transmission.h"
#include "announcer.h"
#include "announcer-common.h"
-#include "crypto.h" /* tr_cryptoRandInt (), tr_cryptoWeakRandInt () */
+#include "crypto-utils.h" /* tr_rand_int (), tr_rand_int_weak () */
#include "log.h"
#include "peer-mgr.h" /* tr_peerMgrCompactToPex () */
#include "ptrarray.h"
a = tr_new0 (tr_announcer, 1);
a->stops = TR_PTR_ARRAY_INIT;
- a->key = tr_cryptoRandInt (INT_MAX);
+ a->key = tr_rand_int (INT_MAX);
a->session = session;
a->slotsAvailable = MAX_CONCURRENT_TASKS;
a->upkeepTimer = evtimer_new (session->event_base, onUpkeepTimer, a);
tier->scrapeIntervalSec = DEFAULT_SCRAPE_INTERVAL_SEC;
tier->announceIntervalSec = DEFAULT_ANNOUNCE_INTERVAL_SEC;
tier->announceMinIntervalSec = DEFAULT_ANNOUNCE_MIN_INTERVAL_SEC;
- tier->scrapeAt = get_next_scrape_time (tor->session, tier, tr_cryptoWeakRandInt (180));
+ tier->scrapeAt = get_next_scrape_time (tor->session, tier, tr_rand_int_weak (180));
tier->tor = tor;
}
{
case 0: return 0;
case 1: return 20;
- case 2: return tr_cryptoWeakRandInt (60) + (60 * 5);
- case 3: return tr_cryptoWeakRandInt (60) + (60 * 15);
- case 4: return tr_cryptoWeakRandInt (60) + (60 * 30);
- case 5: return tr_cryptoWeakRandInt (60) + (60 * 60);
- default: return tr_cryptoWeakRandInt (60) + (60 * 120);
+ case 2: return tr_rand_int_weak (60) + (60 * 5);
+ case 3: return tr_rand_int_weak (60) + (60 * 15);
+ case 4: return tr_rand_int_weak (60) + (60 * 30);
+ case 5: return tr_rand_int_weak (60) + (60 * 60);
+ default: return tr_rand_int_weak (60) + (60 * 120);
}
}
#include "transmission.h"
#include "bandwidth.h"
-#include "crypto.h" /* tr_cryptoWeakRandInt () */
+#include "crypto-utils.h" /* tr_rand_int_weak () */
#include "log.h"
#include "peer-io.h"
#include "utils.h"
dbgmsg ("%d peers to go round-robin for %s", n, (dir==TR_UP?"upload":"download"));
while (n > 0)
{
- const int i = tr_cryptoWeakRandInt (n); /* pick a peer at random */
+ const int i = tr_rand_int_weak (n); /* pick a peer at random */
/* value of 3000 bytes chosen so that when using uTP we'll send a full-size
* frame right away and leave enough buffered data for the next frame to go
#include <string.h> /* strlen () */
#include "transmission.h"
-#include "crypto.h"
+#include "crypto-utils.h"
#include "bitfield.h"
#include "utils.h" /* tr_free */
int end;
int count1;
int count2;
- const int bitCount = 100 + tr_cryptoWeakRandInt (1000);
+ const int bitCount = 100 + tr_rand_int_weak (1000);
tr_bitfield bf;
/* generate a random bitfield */
tr_bitfieldConstruct (&bf, bitCount);
- for (i=0, n=tr_cryptoWeakRandInt (bitCount); i<n; ++i)
- tr_bitfieldAdd (&bf, tr_cryptoWeakRandInt (bitCount));
- begin = tr_cryptoWeakRandInt (bitCount);
+ for (i=0, n=tr_rand_int_weak (bitCount); i<n; ++i)
+ tr_bitfieldAdd (&bf, tr_rand_int_weak (bitCount));
+ begin = tr_rand_int_weak (bitCount);
do
- end = tr_cryptoWeakRandInt (bitCount);
+ end = tr_rand_int_weak (bitCount);
while (end == begin);
/* ensure end <= begin */
#include "transmission.h"
#include "crypto.h"
+#include "crypto-utils.h"
#include "libtransmission-test.h"
return 0;
}
+static int
+test_random (void)
+{
+ int i;
+
+ /* test that tr_rand_int () stays in-bounds */
+ for (i = 0; i < 100000; ++i)
+ {
+ const int val = tr_rand_int (100);
+ check (val >= 0);
+ check (val < 100);
+ }
+
+ return 0;
+}
+
int
main (void)
{
const testFunc tests[] = { test_torrent_hash,
test_encrypt_decrypt,
test_sha1,
- test_ssha1 };
+ test_ssha1,
+ test_random };
return runTests (tests, NUM_TESTS (tests));
}
--- /dev/null
+/*
+ * This file Copyright (C) 2007-2014 Mnemosyne LLC
+ *
+ * It may be used under the GNU GPL versions 2 or 3
+ * or any future license endorsed by Mnemosyne LLC.
+ *
+ * $Id$
+ */
+
+#include <assert.h>
+
+#include <openssl/err.h>
+#include <openssl/rand.h>
+
+#include "transmission.h"
+#include "crypto-utils.h"
+#include "log.h"
+
+/***
+****
+***/
+
+#define MY_NAME "tr_crypto_utils"
+
+static void
+log_openssl_error (const char * file,
+ int line)
+{
+ const unsigned long error_code = ERR_get_error ();
+
+ if (tr_logLevelIsActive (TR_LOG_ERROR))
+ {
+ char buf[512];
+
+#ifndef TR_LIGHTWEIGHT
+ static bool strings_loaded = false;
+ if (!strings_loaded)
+ {
+ ERR_load_crypto_strings ();
+ strings_loaded = true;
+ }
+#endif
+
+ ERR_error_string_n (error_code, buf, sizeof (buf));
+ tr_logAddMessage (file, line, TR_LOG_ERROR, MY_NAME, "OpenSSL error: %s", buf);
+ }
+}
+
+#define log_error() log_openssl_error(__FILE__, __LINE__)
+
+static bool
+check_openssl_result (int result,
+ int expected_result,
+ bool expected_equal,
+ const char * file,
+ int line)
+{
+ const bool ret = (result == expected_result) == expected_equal;
+ if (!ret)
+ log_openssl_error (file, line);
+ return ret;
+}
+
+#define check_result(result) check_openssl_result ((result), 1, true, __FILE__, __LINE__)
+#define check_result_eq(result, x_result) check_openssl_result ((result), (x_result), true, __FILE__, __LINE__)
+#define check_result_neq(result, x_result) check_openssl_result ((result), (x_result), false, __FILE__, __LINE__)
+
+static bool
+check_openssl_pointer (void * pointer,
+ const char * file,
+ int line)
+{
+ const bool ret = pointer != NULL;
+ if (!ret)
+ log_openssl_error (file, line);
+ return ret;
+}
+
+#define check_pointer(pointer) check_openssl_pointer ((pointer), __FILE__, __LINE__)
+
+/***
+****
+***/
+
+bool
+tr_rand_buffer (void * buffer,
+ size_t length)
+{
+ assert (buffer != NULL);
+
+ return check_result (RAND_bytes (buffer, (int) length));
+}
--- /dev/null
+/*
+ * This file Copyright (C) 2007-2014 Mnemosyne LLC
+ *
+ * It may be used under the GNU GPL versions 2 or 3
+ * or any future license endorsed by Mnemosyne LLC.
+ *
+ * $Id$
+ */
+
+#include <assert.h>
+#include <stdlib.h> /* abs (), srand (), rand () */
+
+#include "transmission.h"
+#include "crypto-utils.h"
+#include "utils.h"
+
+/***
+****
+***/
+
+int
+tr_rand_int (int upper_bound)
+{
+ int noise;
+
+ assert (upper_bound > 0);
+
+ while (tr_rand_buffer (&noise, sizeof (noise)))
+ {
+ noise = abs(noise) % upper_bound;
+ /* abs(INT_MIN) is undefined and could return negative value */
+ if (noise >= 0)
+ return noise;
+ }
+
+ /* fall back to a weaker implementation... */
+ return tr_rand_int_weak (upper_bound);
+}
+
+int
+tr_rand_int_weak (int upper_bound)
+{
+ static bool init = false;
+
+ assert (upper_bound > 0);
+
+ if (!init)
+ {
+ srand (tr_time_msec ());
+ init = true;
+ }
+
+ return rand () % upper_bound;
+}
--- /dev/null
+/*
+ * This file Copyright (C) 2007-2014 Mnemosyne LLC
+ *
+ * It may be used under the GNU GPL versions 2 or 3
+ * or any future license endorsed by Mnemosyne LLC.
+ *
+ * $Id$
+ */
+
+#ifndef TR_CRYPTO_UTILS_H
+#define TR_CRYPTO_UTILS_H
+
+#include <stddef.h>
+
+/**
+*** @addtogroup utils Utilities
+*** @{
+**/
+
+/**
+ * @brief Returns a random number in the range of [0...upper_bound).
+ */
+int tr_rand_int (int upper_bound);
+
+/**
+ * @brief Returns a pseudorandom number in the range of [0...upper_bound).
+ *
+ * This is faster, BUT WEAKER, than tr_rand_int () and never be used in sensitive cases.
+ * @see tr_rand_int ()
+ */
+int tr_rand_int_weak (int upper_bound);
+
+/**
+ * @brief Fill a buffer with random bytes.
+ */
+bool tr_rand_buffer (void * buffer,
+ size_t length);
+
+/** @} */
+
+#endif /* TR_CRYPTO_UTILS_H */
*/
#include <assert.h>
-#include <inttypes.h> /* uint8_t */
#include <stdarg.h>
-#include <stdlib.h> /* abs () */
#include <string.h> /* memcpy (), memset (), strcmp () */
#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/rc4.h>
#include <openssl/sha.h>
-#include <openssl/rand.h>
#include "transmission.h"
#include "crypto.h"
+#include "crypto-utils.h"
#include "log.h"
#include "utils.h"
return crypto->torrentHashIsSet;
}
-int
-tr_cryptoRandInt (int upperBound)
-{
- int noise;
- int val;
-
- assert (upperBound > 0);
-
- if (RAND_pseudo_bytes ((unsigned char *) &noise, sizeof noise) >= 0)
- {
- val = abs (noise) % upperBound;
- }
- else /* fall back to a weaker implementation... */
- {
- val = tr_cryptoWeakRandInt (upperBound);
- }
-
- return val;
-}
-
-int
-tr_cryptoWeakRandInt (int upperBound)
-{
- static bool init = false;
-
- assert (upperBound > 0);
-
- if (!init)
- {
- srand (tr_time_msec ());
- init = true;
- }
-
- return rand () % upperBound;
-}
-
-void
-tr_cryptoRandBuf (void * buf, size_t len)
-{
- if (RAND_pseudo_bytes ((unsigned char*)buf, len) != 1)
- logErrorFromSSL ();
-}
-
/***
****
***/
uint8_t sha[SHA_DIGEST_LENGTH];
char buf[2*SHA_DIGEST_LENGTH + saltval_len + 2];
- tr_cryptoRandBuf (salt, saltval_len);
+ tr_rand_buffer (salt, saltval_len);
for (i=0; i<saltval_len; ++i)
salt[i] = salter[ salt[i] % salter_len ];
...) TR_GNUC_NULL_TERMINATED;
-/** @brief returns a random number in the range of [0...n) */
-int tr_cryptoRandInt (int n);
-
-/**
- * @brief returns a pseudorandom number in the range of [0...n)
- *
- * This is faster, BUT WEAKER, than tr_cryptoRandInt () and never
- * be used in sensitive cases.
- * @see tr_cryptoRandInt ()
- */
-int tr_cryptoWeakRandInt (int n);
-
-/** @brief fill a buffer with random bytes */
-void tr_cryptoRandBuf (void * buf, size_t len);
-
/** @brief generate a SSHA password from its plaintext source */
char* tr_ssha1 (const void * plaintext);
#include <winioctl.h> /* FSCTL_SET_SPARSE */
#include "transmission.h"
-#include "crypto.h" /* tr_cryptoRandInt () */
+#include "crypto-utils.h" /* tr_rand_int () */
#include "file.h"
#include "utils.h"
while (i > 0 && path_template[i - 1] == 'X')
{
- const int c = tr_cryptoRandInt (26 + 26 + 10);
+ const int c = tr_rand_int (26 + 26 + 10);
path[i - 1] = c < 26 ? c + 'A' : (c < 26 + 26 ? (c - 26) + 'a' : (c - 26 - 26) + '0');
--i;
}
#include "transmission.h"
#include "clients.h"
-#include "crypto.h"
+#include "crypto-utils.h"
#include "handshake.h"
#include "log.h"
#include "peer-io.h"
walk += len;
/* add some bullshit padding */
- len = tr_cryptoRandInt (PadA_MAXLEN);
- tr_cryptoRandBuf (walk, len);
+ len = tr_rand_int (PadA_MAXLEN);
+ tr_rand_buffer (walk, len);
walk += len;
/* send it */
myKey = tr_cryptoGetMyPublicKey (handshake->crypto, &len);
memcpy (walk, myKey, len);
walk += len;
- len = tr_cryptoRandInt (PadB_MAXLEN);
- tr_cryptoRandBuf (walk, len);
+ len = tr_rand_int (PadB_MAXLEN);
+ tr_rand_buffer (walk, len);
walk += len;
setReadState (handshake, AWAITING_PAD_A);
#include "libtransmission-test.h"
#include "transmission.h"
-#include "crypto.h"
+#include "crypto-utils.h"
#include "file.h"
#include "makemeta.h"
size_t payloadCount;
/* build random payloads */
- payloadCount = 1 + tr_cryptoWeakRandInt (maxFileCount);
+ payloadCount = 1 + tr_rand_int_weak (maxFileCount);
payloads = tr_new0 (void*, payloadCount);
payloadSizes = tr_new0 (size_t, payloadCount);
for (i=0; i<payloadCount; i++)
{
- const size_t n = 1 + tr_cryptoWeakRandInt (maxFileSize);
+ const size_t n = 1 + tr_rand_int_weak (maxFileSize);
payloads[i] = tr_new (char, n);
- tr_cryptoRandBuf (payloads[i], n);
+ tr_rand_buffer (payloads[i], n);
payloadSizes[i] = n;
}
#include "transmission.h"
#include "session.h"
#include "bandwidth.h"
-#include "crypto.h"
#include "log.h"
#include "net.h"
#include "peer-common.h" /* MAX_BLOCK_SIZE */
#include "cache.h"
#include "clients.h"
#include "completion.h"
-#include "crypto.h"
+#include "crypto-utils.h"
#include "handshake.h"
#include "log.h"
#include "net.h"
struct weighted_piece * piece = pieces + i;
piece->index = pool[i];
piece->requestCount = 0;
- piece->salt = tr_cryptoWeakRandInt (4096);
+ piece->salt = tr_rand_int_weak (4096);
}
/* if we already had a list of pieces, merge it into
if (a == NULL)
{
- const int jitter = tr_cryptoWeakRandInt (60*10);
+ const int jitter = tr_rand_int_weak (60*10);
a = tr_new0 (struct peer_atom, 1);
a->addr = *addr;
a->port = port;
rechoke[rechoke_count].peer = peer;
rechoke[rechoke_count].rechoke_state = rechoke_state;
- rechoke[rechoke_count].salt = tr_cryptoWeakRandInt (INT_MAX);
+ rechoke[rechoke_count].salt = tr_rand_int_weak (INT_MAX);
rechoke_count++;
}
n->isInterested = tr_peerMsgsIsPeerInterested (msgs);
n->wasChoked = tr_peerMsgsIsPeerChoked (msgs);
n->rate = getRate (s->tor, atom, now);
- n->salt = tr_cryptoWeakRandInt (INT_MAX);
+ n->salt = tr_rand_int_weak (INT_MAX);
n->isChoked = true;
}
}
if ((n = tr_ptrArraySize (&randPool)))
{
- c = tr_ptrArrayNth (&randPool, tr_cryptoWeakRandInt (n));
+ c = tr_ptrArrayNth (&randPool, tr_rand_int_weak (n));
c->isChoked = false;
s->optimistic = c->msgs;
s->optimisticUnchokeTimeScaler = OPTIMISTIC_UNCHOKE_MULTIPLIER;
if (isPeerCandidate (tor, atom, now))
{
- const uint8_t salt = tr_cryptoWeakRandInt (1024);
+ const uint8_t salt = tr_rand_int_weak (1024);
walk->tor = tor;
walk->atom = atom;
walk->score = getPeerCandidateScore (tor, atom, salt);
#include "transmission.h"
#include "cache.h"
#include "completion.h"
-#include "crypto.h" /* tr_sha1 () */
#include "file.h"
#include "log.h"
#include "peer-io.h"
#include <event2/http_struct.h> /* TODO: eventually remove this */
#include "transmission.h"
-#include "crypto.h" /* tr_cryptoRandBuf (), tr_ssha1_matches () */
+#include "crypto.h" /* tr_ssha1_matches () */
+#include "crypto-utils.h" /* tr_rand_buffer () */
#include "fdlimit.h"
#include "list.h"
#include "log.h"
const size_t pool_size = strlen (pool);
unsigned char * buf = tr_new (unsigned char, n+1);
- tr_cryptoRandBuf (buf, n);
+ tr_rand_buffer (buf, n);
for (i=0; i<n; ++i)
buf[i] = pool[ buf[i] % pool_size ];
buf[n] = '\0';
#include "bandwidth.h"
#include "blocklist.h"
#include "cache.h"
-#include "crypto.h"
+#include "crypto-utils.h"
#include "fdlimit.h"
#include "file.h"
#include "list.h"
static tr_port
getRandomPort (tr_session * s)
{
- return tr_cryptoWeakRandInt (s->randomPortHigh - s->randomPortLow + 1) + s->randomPortLow;
+ return tr_rand_int_weak (s->randomPortHigh - s->randomPortLow + 1) + s->randomPortLow;
}
/* Generate a peer id : "-TRxyzb-" + 12 random alphanumeric
memcpy (buf, PEERID_PREFIX, 8);
- tr_cryptoRandBuf (buf+8, 11);
+ tr_rand_buffer (buf+8, 11);
for (i=8; i<19; ++i)
{
val = buf[i] % base;
#include "cache.h"
#include "completion.h"
#include "crypto.h" /* for tr_sha1 */
+#include "crypto-utils.h"
#include "error.h"
#include "fdlimit.h" /* tr_fdTorrentClose */
#include "file.h"
tr_torrentResetTransferStats (tor);
tr_announcerTorrentStarted (tor);
- tor->dhtAnnounceAt = now + tr_cryptoWeakRandInt (20);
- tor->dhtAnnounce6At = now + tr_cryptoWeakRandInt (20);
+ tor->dhtAnnounceAt = now + tr_rand_int_weak (20);
+ tor->dhtAnnounce6At = now + tr_rand_int_weak (20);
tor->lpdAnnounceAt = now;
tr_peerMgrStartTorrent (tor);
/* libT */
#include "transmission.h"
#include "crypto.h"
+#include "crypto-utils.h"
#include "file.h"
#include "log.h"
#include "net.h"
nap (int roughly_sec)
{
const int roughly_msec = roughly_sec * 1000;
- const int msec = roughly_msec/2 + tr_cryptoWeakRandInt (roughly_msec);
+ const int msec = roughly_msec/2 + tr_rand_int_weak (roughly_msec);
tr_wait_msec (msec);
}
/* Note that DHT ids need to be distributed uniformly,
* so it should be something truly random. */
tr_logAddNamedInfo ("DHT", "Generating new id");
- tr_cryptoRandBuf (myid, 20);
+ tr_rand_buffer (myid, 20);
}
rc = dht_init (ss->udp_socket, ss->udp6_socket, myid, NULL);
tr_threadNew (dht_bootstrap, cl);
dht_timer = evtimer_new (session->event_base, timer_callback, session);
- tr_timerAdd (dht_timer, 0, tr_cryptoWeakRandInt (1000000));
+ tr_timerAdd (dht_timer, 0, tr_rand_int_weak (1000000));
tr_logAddNamedDbg ("DHT", "DHT initialized");
const int rc = tr_dhtAnnounce (tor, AF_INET, 1);
tor->dhtAnnounceAt = now + ((rc == 0)
- ? 5 + tr_cryptoWeakRandInt (5)
- : 25 * 60 + tr_cryptoWeakRandInt (3*60));
+ ? 5 + tr_rand_int_weak (5)
+ : 25 * 60 + tr_rand_int_weak (3*60));
}
if (tor->dhtAnnounce6At <= now)
const int rc = tr_dhtAnnounce (tor, AF_INET6, 1);
tor->dhtAnnounce6At = now + ((rc == 0)
- ? 5 + tr_cryptoWeakRandInt (5)
- : 25 * 60 + tr_cryptoWeakRandInt (3*60));
+ ? 5 + tr_rand_int_weak (5)
+ : 25 * 60 + tr_rand_int_weak (3*60));
}
}
}
/* Being slightly late is fine,
and has the added benefit of adding some jitter. */
- tr_timerAdd (dht_timer, tosleep, tr_cryptoWeakRandInt (1000000));
+ tr_timerAdd (dht_timer, tosleep, tr_rand_int_weak (1000000));
}
static void
int
dht_random_bytes (void * buf, size_t size)
{
- tr_cryptoRandBuf (buf, size);
+ tr_rand_buffer (buf, size);
return size;
}
#include "log.h"
#include "net.h"
#include "session.h"
-#include "crypto.h" /* tr_cryptoWeakRandInt () */
+#include "crypto-utils.h" /* tr_rand_int_weak () */
#include "peer-mgr.h"
#include "tr-utp.h"
#include "utils.h"
int usec;
if (tr_sessionIsUTPEnabled (ss)) {
sec = 0;
- usec = UTP_INTERVAL_US / 2 + tr_cryptoWeakRandInt (UTP_INTERVAL_US);
+ usec = UTP_INTERVAL_US / 2 + tr_rand_int_weak (UTP_INTERVAL_US);
} else {
/* If somebody has disabled uTP, then we still want to run
UTP_CheckTimeouts, in order to let closed sockets finish
interested in that happening in a timely manner, we might as
well use a large timeout. */
sec = 2;
- usec = tr_cryptoWeakRandInt (1000000);
+ usec = tr_rand_int_weak (1000000);
}
tr_timerAdd (utp_timer, sec, usec);
}
#include "transmission.h"
#include "ConvertUTF.h" /* tr_utf8_validate*/
#include "platform.h"
-#include "crypto.h"
+#include "crypto-utils.h" /* tr_rand_int_weak */
#include "utils.h"
#include "web.h"
/* populate buf with random ints */
for (i=0; i<n; ++i)
- buf[i] = tr_cryptoWeakRandInt (range);
+ buf[i] = tr_rand_int_weak (range);
/* find the best k */
tr_quickfindFirstK (buf, n, sizeof(int), compareInts, k);
return 0;
}
-static int
-test_cryptoRand (void)
-{
- int i;
-
- /* test that tr_cryptoRandInt () stays in-bounds */
- for (i = 0; i < 100000; ++i)
- {
- const int val = tr_cryptoRandInt (100);
- check (val >= 0);
- check (val < 100);
- }
-
- return 0;
-}
-
static char *
test_strdup_printf_valist (const char * fmt, ...)
{
const testFunc tests[] = { test_array,
test_base64,
test_buildpath,
- test_cryptoRand,
test_hex,
test_lowerbound,
test_quickfindFirst,