]> granicus.if.org Git - transmission/commitdiff
#4400, #5462: Move SHA1 helpers to crypto-utils
authorMike Gelfand <mikedld@mikedld.com>
Thu, 4 Dec 2014 12:13:59 +0000 (12:13 +0000)
committerMike Gelfand <mikedld@mikedld.com>
Thu, 4 Dec 2014 12:13:59 +0000 (12:13 +0000)
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing SHA1 calculation to crypto-utils.{c,h}. OpenSSL-related
functionality (SHA1 context management) is moved to crypto-utils-openssl.c.

Add new tr_sha1_ctx_t type and functions to be implemented by crypto
backends:
* tr_sha1_init - allocate SHA1 context and and initialize it,
* tr_sha1_update - hash some [more] data,
* tr_sha1_final - finish hash calculation and free the context.

Add new files to CMakeLists.txt (leftover from previous commit) to fix
CMake-based configuration.

14 files changed:
libtransmission/CMakeLists.txt
libtransmission/crypto-test.c
libtransmission/crypto-utils-openssl.c
libtransmission/crypto-utils.c
libtransmission/crypto-utils.h
libtransmission/crypto.c
libtransmission/crypto.h
libtransmission/inout.c
libtransmission/makemeta.c
libtransmission/metainfo.c
libtransmission/torrent-magnet.c
libtransmission/torrent.c
libtransmission/tr-dht.c
libtransmission/verify.c

index f987f99ec3116f7a80f1296054a9eafc421595ee..30ff96022362cd4b5866a00a8a376a18885e2245 100644 (file)
@@ -14,6 +14,8 @@ set(${PROJECT_NAME}_SOURCES
     completion.c
     ConvertUTF.c
     crypto.c
+    crypto-utils.c
+    crypto-utils-openssl.c
     error.c
     fdlimit.c
     file.c
@@ -91,6 +93,7 @@ set(${PROJECT_NAME}_PRIVATE_HEADERS
     completion.h
     ConvertUTF.h
     crypto.h
+    crypto-utils.h
     fdlimit.h
     handshake.h
     history.h
index 3a76226ef96e971826a8e56386478e52ada35f00..df283b0085a39b555dc260d7cc45ac5476499bdf 100644 (file)
@@ -99,10 +99,10 @@ test_sha1 (void)
 {
   uint8_t hash[SHA_DIGEST_LENGTH];
 
-  tr_sha1 (hash, "test", 4, NULL);
+  check (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 (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;
index 556573b29404845be61085bb2345f86514464425..187288875aecf30f2159067cb5694b5d3c60160c 100644 (file)
@@ -10,6 +10,7 @@
 #include <assert.h>
 
 #include <openssl/err.h>
+#include <openssl/evp.h>
 #include <openssl/rand.h>
 
 #include "transmission.h"
@@ -82,6 +83,54 @@ check_openssl_pointer (void       * pointer,
 ****
 ***/
 
+tr_sha1_ctx_t
+tr_sha1_init (void)
+{
+  EVP_MD_CTX * handle = EVP_MD_CTX_create ();
+
+  if (check_result (EVP_DigestInit_ex (handle, EVP_sha1 (), NULL)))
+    return handle;
+
+  EVP_MD_CTX_destroy (handle);
+  return NULL;
+}
+
+bool
+tr_sha1_update (tr_sha1_ctx_t   handle,
+                const void    * data,
+                size_t          data_length)
+{
+  assert (handle != NULL);
+  assert (data != NULL);
+
+  return check_result (EVP_DigestUpdate (handle, data, data_length));
+}
+
+bool
+tr_sha1_final (tr_sha1_ctx_t   handle,
+               uint8_t       * hash)
+{
+  bool ret = true;
+
+  if (hash != NULL)
+    {
+      unsigned int hash_length;
+
+      assert (handle != NULL);
+
+      ret = check_result (EVP_DigestFinal_ex (handle, hash, &hash_length));
+
+      assert (!ret || hash_length == SHA_DIGEST_LENGTH);
+    }
+
+  EVP_MD_CTX_destroy (handle);
+  return ret;
+}
+
+/***
+****
+***/
+
 bool
 tr_rand_buffer (void   * buffer,
                 size_t   length)
index 0be91772dd3a3903921a017c5b1212efe02fedfb..f6f0273ab1c8f12f906943d1d02bb20aadb74576 100644 (file)
@@ -8,6 +8,7 @@
  */
 
 #include <assert.h>
+#include <stdarg.h>
 #include <stdlib.h> /* abs (), srand (), rand () */
 
 #include "transmission.h"
 ****
 ***/
 
+bool
+tr_sha1 (uint8_t    * hash,
+         const void * data1,
+         int          data1_length,
+                      ...)
+{
+  tr_sha1_ctx_t sha;
+
+  if ((sha = tr_sha1_init ()) == NULL)
+    return false;
+
+  if (tr_sha1_update (sha, data1, data1_length))
+    {
+      va_list vl;
+      const void * data;
+
+      va_start (vl, data1_length);
+      while ((data = va_arg (vl, const void *)) != NULL)
+        {
+          const int data_length = va_arg (vl, int);
+          assert (data_length >= 0);
+          if (!tr_sha1_update (sha, data, data_length))
+            break;
+        }
+      va_end (vl);
+
+      /* did we reach the end of argument list? */
+      if (data == NULL)
+        return tr_sha1_final (sha, hash);
+    }
+
+  tr_sha1_final (sha, NULL);
+  return false;
+}
+
+/***
+****
+***/
+
 int
 tr_rand_int (int upper_bound)
 {
index 5189e12e63038d1307b76e1be40da3218da99374..a839775c604af17def0054ef34ea81da34ce6dd5 100644 (file)
 #ifndef TR_CRYPTO_UTILS_H
 #define TR_CRYPTO_UTILS_H
 
+#include <inttypes.h>
 #include <stddef.h>
 
+#include "utils.h" /* TR_GNUC_NULL_TERMINATED */
+
 /**
 *** @addtogroup utils Utilities
 *** @{
 **/
 
+ /** @brief Opaque SHA1 context type. */
+typedef void * tr_sha1_ctx_t;
+
+/**
+ * @brief Generate a SHA1 hash from one or more chunks of memory.
+ */
+bool             tr_sha1               (uint8_t        * hash,
+                                        const void     * data1,
+                                        int              data1_length,
+                                                         ...) TR_GNUC_NULL_TERMINATED;
+
+/**
+ * @brief Allocate and initialize new SHA1 hasher context.
+ */
+tr_sha1_ctx_t    tr_sha1_init          (void);
+
+/**
+ * @brief Update SHA1 hash.
+ */
+bool             tr_sha1_update        (tr_sha1_ctx_t    handle,
+                                        const void     * data,
+                                        size_t           data_length);
+
+/**
+ * @brief Finalize and export SHA1 hash, free hasher context.
+ */
+bool             tr_sha1_final         (tr_sha1_ctx_t    handle,
+                                        uint8_t        * hash);
 /**
  * @brief Returns a random number in the range of [0...upper_bound).
  */
index d801cdc28940892dd3d158ef761e250f8616a5f3..31b8bf9b93d24aae150d8d0ce0da77ffada27387 100644 (file)
@@ -15,7 +15,6 @@
 #include <openssl/dh.h>
 #include <openssl/err.h>
 #include <openssl/rc4.h>
-#include <openssl/sha.h>
 
 #include "transmission.h"
 #include "crypto.h"
 ***
 **/
 
-void
-tr_sha1 (uint8_t * setme, const void * content1, int content1_len, ...)
-{
-  va_list vl;
-  SHA_CTX sha;
-  const void * content;
-
-  SHA1_Init (&sha);
-  SHA1_Update (&sha, content1, content1_len);
-
-  va_start (vl, content1_len);
-  while ((content = va_arg (vl, const void*)))
-    SHA1_Update (&sha, content, va_arg (vl, int));
-  va_end (vl);
-
-  SHA1_Final (setme, &sha);
-}
-
-/**
-***
-**/
-
 #define KEY_LEN 96
 
 #define PRIME_LEN 96
@@ -198,24 +175,17 @@ initRC4 (tr_crypto  * crypto,
          RC4_KEY    * setme,
          const char * key)
 {
-  SHA_CTX sha;
   uint8_t buf[SHA_DIGEST_LENGTH];
 
   assert (crypto->torrentHashIsSet);
   assert (crypto->mySecretIsSet);
 
-  if (SHA1_Init (&sha)
-      && SHA1_Update (&sha, key, 4)
-      && SHA1_Update (&sha, crypto->mySecret, KEY_LEN)
-      && SHA1_Update (&sha, crypto->torrentHash, SHA_DIGEST_LENGTH)
-      && SHA1_Final (buf, &sha))
-    {
-      RC4_set_key (setme, SHA_DIGEST_LENGTH, buf);
-    }
-  else
-    {
-      logErrorFromSSL ();
-    }
+  if (tr_sha1 (buf,
+               key, 4,
+               crypto->mySecret, KEY_LEN,
+               crypto->torrentHash, SHA_DIGEST_LENGTH,
+               NULL))
+    RC4_set_key (setme, SHA_DIGEST_LENGTH, buf);
 }
 
 void
index 9728179502d7c8330be4ea0a8a6bac12f674536c..985c901418ce6a307e94339be09761ed75c7e776 100644 (file)
@@ -86,14 +86,6 @@ void           tr_cryptoEncrypt (tr_crypto *  crypto,
 *** @{
 **/
 
-
-/** @brief generate a SHA1 hash from one or more chunks of memory */
-void tr_sha1 (uint8_t    * setme,
-              const void * content1,
-              int          content1_len,
-              ...) TR_GNUC_NULL_TERMINATED;
-
-
 /** @brief generate a SSHA password from its plaintext source */
 char*  tr_ssha1 (const void * plaintext);
 
index 63bd1874a46bfc23ac1bc0ce05917794594411b9..82a769380ae0a342b5d1a3a2c18c333128420d0c 100644 (file)
 #include <stdlib.h> /* bsearch () */
 #include <string.h> /* memcmp () */
 
-#include <openssl/sha.h>
-
 #include "transmission.h"
 #include "cache.h" /* tr_cacheReadBlock () */
+#include "crypto-utils.h"
 #include "error.h"
 #include "fdlimit.h"
 #include "file.h"
@@ -278,7 +277,7 @@ recalculateHash (tr_torrent * tor, tr_piece_index_t pieceIndex, uint8_t * setme)
   bool  success = true;
   const size_t buflen = tor->blockSize;
   void * buffer = tr_valloc (buflen);
-  SHA_CTX  sha;
+  tr_sha1_ctx_t sha;
 
   assert (tor != NULL);
   assert (pieceIndex < tor->info.pieceCount);
@@ -286,7 +285,7 @@ recalculateHash (tr_torrent * tor, tr_piece_index_t pieceIndex, uint8_t * setme)
   assert (buflen > 0);
   assert (setme != NULL);
 
-  SHA1_Init (&sha);
+  sha = tr_sha1_init ();
   bytesLeft = tr_torPieceCountBytes (tor, pieceIndex);
 
   tr_ioPrefetch (tor, pieceIndex, offset, bytesLeft);
@@ -297,13 +296,12 @@ recalculateHash (tr_torrent * tor, tr_piece_index_t pieceIndex, uint8_t * setme)
       success = !tr_cacheReadBlock (tor->session->cache, tor, pieceIndex, offset, len, buffer);
       if (!success)
         break;
-      SHA1_Update (&sha, buffer, len);
+      tr_sha1_update (sha, buffer, len);
       offset += len;
       bytesLeft -= len;
     }
 
-  if (success)
-    SHA1_Final (setme, &sha);
+  tr_sha1_final (sha, success ? setme : NULL);
 
   tr_free (buffer);
   return success;
index df8e727f2842e2d12543c17732e89a52a08e80cd..26f39d0610da0b1c86ae9f6162013b228d67915c 100644 (file)
@@ -15,7 +15,7 @@
 #include <event2/util.h> /* evutil_ascii_strcasecmp () */
 
 #include "transmission.h"
-#include "crypto.h" /* tr_sha1 */
+#include "crypto-utils.h" /* tr_sha1 */
 #include "error.h"
 #include "file.h"
 #include "log.h"
index c7f3581dc7a5cfdaa45ae79849adcfbdd471b863..9a913cfe6900258c8ae895c349e37d952dbfa983 100644 (file)
@@ -13,7 +13,7 @@
 #include <event2/buffer.h>
 
 #include "transmission.h"
-#include "crypto.h" /* tr_sha1 */
+#include "crypto-utils.h" /* tr_sha1 */
 #include "file.h"
 #include "log.h"
 #include "metainfo.h"
index cad15ead4f460c316e07792bca508e19249fa615..8500865991de560dd2628044c3dea2f14d90195d 100644 (file)
@@ -13,7 +13,7 @@
 #include <event2/buffer.h>
 
 #include "transmission.h"
-#include "crypto.h" /* tr_sha1 () */
+#include "crypto-utils.h" /* tr_sha1 () */
 #include "file.h"
 #include "log.h"
 #include "magnet.h"
index ea2e8d45001f9e75cb8b3081e7e4e15f4724bdf7..ff36fb8e60ed953a88207da3c1270b2ff6c9c12a 100644 (file)
@@ -19,6 +19,7 @@
 #include <assert.h>
 #include <math.h>
 #include <stdarg.h>
+#include <stdio.h> /* remove () */
 #include <string.h> /* memcmp */
 #include <stdlib.h> /* qsort */
 #include <limits.h> /* INT_MAX */
@@ -30,8 +31,7 @@
 #include "bandwidth.h"
 #include "cache.h"
 #include "completion.h"
-#include "crypto.h" /* for tr_sha1 */
-#include "crypto-utils.h"
+#include "crypto-utils.h" /* for tr_sha1 */
 #include "error.h"
 #include "fdlimit.h" /* tr_fdTorrentClose */
 #include "file.h"
index e40d268322f64b76b0ca6908d88244003a38b70d..23a03b621b29f1f9443a13d8becfc608007aeaa9 100644 (file)
@@ -49,7 +49,6 @@
 
 /* libT */
 #include "transmission.h"
-#include "crypto.h"
 #include "crypto-utils.h"
 #include "file.h"
 #include "log.h"
index 1c1129694375b663887f4be9766c98818195216a..cad8ff83b91717366664bd58f10ed6f85fdc0811 100644 (file)
  #include <fcntl.h> /* posix_fadvise () */
 #endif
 
-#include <openssl/sha.h>
-
 #include "transmission.h"
 #include "completion.h"
+#include "crypto-utils.h"
 #include "file.h"
 #include "list.h"
 #include "log.h"
@@ -40,7 +39,7 @@ static bool
 verifyTorrent (tr_torrent * tor, bool * stopFlag)
 {
   time_t end;
-  SHA_CTX sha;
+  tr_sha1_ctx_t sha;
   tr_sys_file_t fd = TR_BAD_SYS_FILE;
   uint64_t filePos = 0;
   bool changed = false;
@@ -54,7 +53,7 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag)
   const size_t buflen = 1024 * 128; /* 128 KiB buffer */
   uint8_t * buffer = tr_valloc (buflen);
 
-  SHA1_Init (&sha);
+  sha = tr_sha1_init ();
 
   tr_logAddTorDbg (tor, "%s", "verifying torrent...");
   tr_torrentSetChecked (tor, 0);
@@ -92,7 +91,7 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag)
           if (tr_sys_file_read_at (fd, buffer, bytesThisPass, filePos, &numRead, NULL) && numRead > 0)
             {
               bytesThisPass = numRead;
-              SHA1_Update (&sha, buffer, bytesThisPass);
+              tr_sha1_update (sha, buffer, bytesThisPass);
 #if defined HAVE_POSIX_FADVISE && defined POSIX_FADV_DONTNEED
               posix_fadvise (fd, filePos, bytesThisPass, POSIX_FADV_DONTNEED);
 #endif
@@ -112,7 +111,7 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag)
           bool hasPiece;
           uint8_t hash[SHA_DIGEST_LENGTH];
 
-          SHA1_Final (hash, &sha);
+          tr_sha1_final (sha, hash);
           hasPiece = !memcmp (hash, tor->info.pieces[pieceIndex].hash, SHA_DIGEST_LENGTH);
 
           if (hasPiece || hadPiece)
@@ -133,7 +132,7 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag)
               tr_wait_msec (MSEC_TO_SLEEP_PER_SECOND_DURING_VERIFY);
             }
 
-          SHA1_Init (&sha);
+          sha = tr_sha1_init ();
           pieceIndex++;
           piecePos = 0;
         }
@@ -154,6 +153,7 @@ verifyTorrent (tr_torrent * tor, bool * stopFlag)
   /* cleanup */
   if (fd != TR_BAD_SYS_FILE)
     tr_sys_file_close (fd, NULL);
+  tr_sha1_final (sha, NULL);
   free (buffer);
 
   /* stopwatch */