]> granicus.if.org Git - transmission/commitdiff
(trunk, libT) #5573 'crypto unit test' -- written by mike.dld
authorJordan Lee <jordan@transmissionbt.com>
Sun, 19 Jan 2014 04:41:20 +0000 (04:41 +0000)
committerJordan Lee <jordan@transmissionbt.com>
Sun, 19 Jan 2014 04:41:20 +0000 (04:41 +0000)
libtransmission/Makefile.am
libtransmission/crypto-test.c [new file with mode: 0644]

index 2e63acd53324599e3ce77c84c70a09aa8d6f0f1a..0057a5529a75d906f13cf2770aef892cbc6c33fb 100644 (file)
@@ -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 (file)
index 0000000..6cbd44c
--- /dev/null
@@ -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 <string.h>
+
+#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));
+}