From 2ec84b2e32af14fe3ee1d57bd4ff4fb73e18ea08 Mon Sep 17 00:00:00 2001 From: Jordan Lee Date: Sun, 19 Jan 2014 04:41:20 +0000 Subject: [PATCH] (trunk, libT) #5573 'crypto unit test' -- written by mike.dld --- libtransmission/Makefile.am | 5 + libtransmission/crypto-test.c | 182 ++++++++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 libtransmission/crypto-test.c diff --git a/libtransmission/Makefile.am b/libtransmission/Makefile.am index 2e63acd53..0057a5529 100644 --- a/libtransmission/Makefile.am +++ b/libtransmission/Makefile.am @@ -132,6 +132,7 @@ TESTS = \ bitfield-test \ blocklist-test \ clients-test \ + crypto-test \ history-test \ json-test \ magnet-test \ @@ -178,6 +179,10 @@ clients_test_SOURCES = clients-test.c $(TEST_SOURCES) clients_test_LDADD = ${apps_ldadd} clients_test_LDFLAGS = ${apps_ldflags} +crypto_test_SOURCES = crypto-test.c $(TEST_SOURCES) +crypto_test_LDADD = ${apps_ldadd} +crypto_test_LDFLAGS = ${apps_ldflags} + history_test_SOURCES = history-test.c $(TEST_SOURCES) history_test_LDADD = ${apps_ldadd} history_test_LDFLAGS = ${apps_ldflags} diff --git a/libtransmission/crypto-test.c b/libtransmission/crypto-test.c new file mode 100644 index 000000000..6cbd44c5c --- /dev/null +++ b/libtransmission/crypto-test.c @@ -0,0 +1,182 @@ +/* + * This file Copyright (C) 2013-2014 Mnemosyne LLC + * + * It may be used under the GNU Public License v2 or v3 licenses, + * or any future license endorsed by Mnemosyne LLC. + * + * $Id$ + */ + +#include + +#include "transmission.h" +#include "crypto.h" + +#include "libtransmission-test.h" + +#define SHA_DIGEST_LENGTH 20 + +static int +test_torrent_hash (void) +{ + tr_crypto a; + uint8_t hash[SHA_DIGEST_LENGTH]; + int i; + + for (i = 0; i < SHA_DIGEST_LENGTH; ++i) + hash[i] = i; + + tr_cryptoConstruct (&a, NULL, true); + + check (!tr_cryptoHasTorrentHash (&a)); +#ifdef NDEBUG + check (tr_cryptoGetTorrentHash (&a) == NULL); +#endif + + tr_cryptoSetTorrentHash (&a, hash); + check (tr_cryptoHasTorrentHash (&a)); + check (tr_cryptoGetTorrentHash (&a) != NULL); + check (memcmp (tr_cryptoGetTorrentHash (&a), hash, SHA_DIGEST_LENGTH) == 0); + + tr_cryptoDestruct (&a); + + for (i = 0; i < SHA_DIGEST_LENGTH; ++i) + hash[i] = i + 1; + + tr_cryptoConstruct (&a, hash, false); + + check (tr_cryptoHasTorrentHash (&a)); + check (tr_cryptoGetTorrentHash (&a) != NULL); + check (memcmp (tr_cryptoGetTorrentHash (&a), hash, SHA_DIGEST_LENGTH) == 0); + + tr_cryptoSetTorrentHash (&a, NULL); + check (!tr_cryptoHasTorrentHash (&a)); +#ifdef NDEBUG + check (tr_cryptoGetTorrentHash (&a) == NULL); +#endif + + tr_cryptoDestruct (&a); + + return 0; +} + +static int +test_encrypt_decrypt (void) +{ + tr_crypto a, b; + uint8_t hash[SHA_DIGEST_LENGTH]; + const char test1[] = { "test1" }; + char buf11[sizeof (test1)], buf12[sizeof (test1)]; + const char test2[] = { "@#)C$@)#(*%bvkdjfhwbc039bc4603756VB3)" }; + char buf21[sizeof (test2)], buf22[sizeof (test2)]; + int i; + + for (i = 0; i < SHA_DIGEST_LENGTH; ++i) + hash[i] = i; + + tr_cryptoConstruct (&a, hash, false); + tr_cryptoConstruct (&b, hash, true); + tr_cryptoComputeSecret (&a, tr_cryptoGetMyPublicKey (&b, &i)); + tr_cryptoComputeSecret (&b, tr_cryptoGetMyPublicKey (&a, &i)); + + tr_cryptoEncryptInit (&a); + tr_cryptoEncrypt (&a, sizeof (test1), test1, buf11); + tr_cryptoDecryptInit (&b); + tr_cryptoDecrypt (&b, sizeof (test1), buf11, buf12); + check_streq (test1, buf12); + + tr_cryptoEncryptInit (&b); + tr_cryptoEncrypt (&b, sizeof (test2), test2, buf21); + tr_cryptoDecryptInit (&a); + tr_cryptoDecrypt (&a, sizeof (test2), buf21, buf22); + check_streq (test2, buf22); + + tr_cryptoDestruct (&b); + tr_cryptoDestruct (&a); + + return 0; +} + +static int +test_sha1 (void) +{ + uint8_t hash[SHA_DIGEST_LENGTH]; + + tr_sha1 (hash, "test", 4, NULL); + check (memcmp (hash, "\xa9\x4a\x8f\xe5\xcc\xb1\x9b\xa6\x1c\x4c\x08\x73\xd3\x91\xe9\x87\x98\x2f\xbb\xd3", SHA_DIGEST_LENGTH) == 0); + + tr_sha1 (hash, "1", 1, "22", 2, "333", 3, NULL); + check (memcmp (hash, "\x1f\x74\x64\x8e\x50\xa6\xa6\x70\x8e\xc5\x4a\xb3\x27\xa1\x63\xd5\x53\x6b\x7c\xed", SHA_DIGEST_LENGTH) == 0); + + return 0; +} + +static int +test_ssha1 (void) +{ + const char * const test_data[] = + { + "test", + "QNY)(*#$B)!_X$B !_B#($^!)*&$%CV!#)&$C!@$(P*)" + }; + + size_t i; + +#define HASH_COUNT (16 * 1024) + + for (i = 0; i < sizeof (test_data) / sizeof (*test_data); ++i) + { + char * const phrase = tr_strdup (test_data[i]); + char ** hashes = tr_new (char *, HASH_COUNT); + size_t j; + + for (j = 0; j < HASH_COUNT; ++j) + { + hashes[j] = tr_ssha1 (phrase); + + check (hashes[j] != NULL); + + /* phrase matches each of generated hashes */ + check (tr_ssha1_matches (hashes[j], phrase)); + } + + for (j = 0; j < HASH_COUNT; ++j) + { + size_t k; + + /* all hashes are different */ + for (k = 0; k < HASH_COUNT; ++k) + check (k == j || strcmp (hashes[j], hashes[k]) != 0); + } + + /* exchange two first chars */ + phrase[0] ^= phrase[1]; + phrase[1] ^= phrase[0]; + phrase[0] ^= phrase[1]; + + for (j = 0; j < HASH_COUNT; ++j) + /* changed phrase doesn't match the hashes */ + check (!tr_ssha1_matches (hashes[j], phrase)); + + for (j = 0; j < HASH_COUNT; ++j) + tr_free (hashes[j]); + + tr_free (hashes); + tr_free (phrase); + } + +#undef HASH_COUNT + + return 0; +} + +int +main (void) +{ + const testFunc tests[] = { test_torrent_hash, + test_encrypt_decrypt, + test_sha1, + test_ssha1 }; + + return runTests (tests, NUM_TESTS (tests)); +} -- 2.40.0