]> granicus.if.org Git - transmission/commitdiff
Simplify `tr_ssha1_matches` logic
authorMike Gelfand <mikedld@mikedld.com>
Mon, 9 Jan 2017 11:15:07 +0000 (14:15 +0300)
committerMike Gelfand <mikedld@mikedld.com>
Mon, 9 Jan 2017 11:15:07 +0000 (14:15 +0300)
Gets rid of needless heap memory allocations and copying. Convert SHA1 hash
to hex in-place.

Fixes: #141
libtransmission/crypto-utils.c
libtransmission/utils.c

index 82b44db97ba3b7a8320fcc75ddeb8679c490c473..34ca86af1da1ae8f0eec096a8edb5484f3dc51e3 100644 (file)
@@ -132,6 +132,8 @@ tr_ssha1 (const char * plain_text)
                                "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                                "./";
 
+  assert (plain_text != NULL);
+
   size_t i;
   unsigned char salt[saltval_len];
   uint8_t sha[SHA_DIGEST_LENGTH];
@@ -154,34 +156,27 @@ bool
 tr_ssha1_matches (const char * ssha1,
                   const char * plain_text)
 {
-  char * salt;
-  size_t saltlen;
-  char * my_ssha1;
-  uint8_t buf[SHA_DIGEST_LENGTH];
-  bool result;
-  const size_t sourcelen = strlen (ssha1);
+  assert (ssha1 != NULL);
+  assert (plain_text != NULL);
 
-  /* extract the salt */
-  if (sourcelen < 2 * SHA_DIGEST_LENGTH - 1)
+  const size_t brace_len = 1;
+  const size_t brace_and_hash_len = brace_len + 2 * SHA_DIGEST_LENGTH;
+
+  const size_t source_len = strlen (ssha1);
+  if (source_len < brace_and_hash_len || ssha1[0] != '{')
     return false;
-  saltlen = sourcelen - 2 * SHA_DIGEST_LENGTH - 1;
-  salt = tr_malloc (saltlen);
-  memcpy (salt, ssha1 + 2 * SHA_DIGEST_LENGTH + 1, saltlen);
 
-  /* hash pass + salt */
-  my_ssha1 = tr_malloc (2 * SHA_DIGEST_LENGTH + saltlen + 2);
-  tr_sha1 (buf, plain_text, (int) strlen (plain_text), salt, (int) saltlen, NULL);
-  tr_sha1_to_hex (&my_ssha1[1], buf);
-  memcpy (my_ssha1 + 1 + 2 * SHA_DIGEST_LENGTH, salt, saltlen);
-  my_ssha1[1 + 2 * SHA_DIGEST_LENGTH + saltlen] = '\0';
-  my_ssha1[0] = '{';
+  /* extract the salt */
+  const char * const salt = ssha1 + brace_and_hash_len;
+  const size_t salt_len = source_len - brace_and_hash_len;
 
-  result = strcmp (ssha1, my_ssha1) == 0;
+  uint8_t buf[SHA_DIGEST_LENGTH * 2 + 1];
 
-  tr_free (my_ssha1);
-  tr_free (salt);
+  /* hash pass + salt */
+  tr_sha1 (buf, plain_text, (int) strlen (plain_text), salt, (int) salt_len, NULL);
+  tr_sha1_to_hex ((char *) buf, buf);
 
-  return result;
+  return strncmp (ssha1 + brace_len, (const char *) buf, SHA_DIGEST_LENGTH * 2) == 0;
 }
 
 /***
index cb42f79a4b4a37c9d74c3e8e731e8727f41e8a8a..8dfd6328048776abc24bf0294d9e63c7a9378af1 100644 (file)
@@ -635,16 +635,19 @@ tr_binary_to_hex (const void * input,
 {
   static const char hex[] = "0123456789abcdef";
   const uint8_t * input_octets = input;
-  size_t i;
 
-  for (i = 0; i < byte_length; ++i)
-    {
-      const unsigned int val = *input_octets++;
-      *output++ = hex[val >> 4];
-      *output++ = hex[val & 0xf];
-    }
+  /* go from back to front to allow for in-place conversion */
+  input_octets += byte_length;
+  output += byte_length * 2;
 
   *output = '\0';
+
+  while (byte_length-- > 0)
+    {
+      const unsigned int val = *(--input_octets);
+      *(--output) = hex[val & 0xf];
+      *(--output) = hex[val >> 4];
+    }
 }
 
 void