From: Mike Gelfand Date: Thu, 4 Dec 2014 20:45:18 +0000 (+0000) Subject: #4400, #5462: Move SSHA1 helpers to crypto-utils X-Git-Tag: 2.90~332 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=748f8a75d2a12b4b41a3ceb0e2d2be80e771d96d;p=transmission #4400, #5462: Move SSHA1 helpers to crypto-utils 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 SSHA1 password generation and checking to crypto-utils.{c,h}. --- diff --git a/libtransmission/crypto-utils.c b/libtransmission/crypto-utils.c index b91c268cb..7b3bff48d 100644 --- a/libtransmission/crypto-utils.c +++ b/libtransmission/crypto-utils.c @@ -10,7 +10,7 @@ #include #include #include /* abs (), srand (), rand () */ -#include /* memmove (), memset (), strlen () */ +#include /* memcpy (), memmove (), memset (), strcmp (), strlen () */ #include "transmission.h" #include "crypto-utils.h" @@ -120,6 +120,72 @@ tr_rand_int_weak (int upper_bound) **** ***/ +char * +tr_ssha1 (const char * plain_text) +{ + enum { saltval_len = 8, + salter_len = 64 }; + static const char * salter = "0123456789" + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "./"; + + size_t i; + unsigned char salt[saltval_len]; + uint8_t sha[SHA_DIGEST_LENGTH]; + char buf[2 * SHA_DIGEST_LENGTH + saltval_len + 2]; + + tr_rand_buffer (salt, saltval_len); + for (i = 0; i < saltval_len; ++i) + salt[i] = salter[salt[i] % salter_len]; + + tr_sha1 (sha, plain_text, strlen (plain_text), salt, (size_t) saltval_len, NULL); + tr_sha1_to_hex (&buf[1], sha); + memcpy (&buf[1 + 2 * SHA_DIGEST_LENGTH], &salt, saltval_len); + buf[1 + 2 * SHA_DIGEST_LENGTH + saltval_len] = '\0'; + buf[0] = '{'; /* signal that this is a hash. this makes saving/restoring easier */ + + return tr_strdup (buf); +} + +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); + + /* extract the salt */ + if (sourcelen < 2 * SHA_DIGEST_LENGTH - 1) + 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, strlen (plain_text), salt, 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] = '{'; + + result = strcmp (ssha1, my_ssha1) == 0; + + tr_free (my_ssha1); + tr_free (salt); + + return result; +} + +/*** +**** +***/ + void * tr_base64_encode (const void * input, size_t input_length, diff --git a/libtransmission/crypto-utils.h b/libtransmission/crypto-utils.h index de8e34075..f6bc0a988 100644 --- a/libtransmission/crypto-utils.h +++ b/libtransmission/crypto-utils.h @@ -154,6 +154,17 @@ int tr_rand_int_weak (int upper_bound); bool tr_rand_buffer (void * buffer, size_t length); +/** + * @brief Generate a SSHA password from its plaintext source. + */ +char * tr_ssha1 (const char * plain_text) TR_GNUC_MALLOC; + +/** + * @brief Validate a test password against the a ssha1 password. + */ +bool tr_ssha1_matches (const char * ssha1, + const char * plain_text); + /** * @brief Translate a block of bytes into base64. * @return a newly-allocated null-terminated string that can be freed with tr_free () diff --git a/libtransmission/crypto.c b/libtransmission/crypto.c index d7ece4432..1997ceed6 100644 --- a/libtransmission/crypto.c +++ b/libtransmission/crypto.c @@ -8,7 +8,7 @@ */ #include -#include /* memcpy (), memmove (), memset (), strcmp () */ +#include /* memcpy (), memmove (), memset () */ #include "transmission.h" #include "crypto.h" @@ -219,68 +219,3 @@ tr_cryptoHasTorrentHash (const tr_crypto * crypto) return crypto->torrentHashIsSet; } - -/*** -**** -***/ - -char* -tr_ssha1 (const void * plaintext) -{ - enum { saltval_len = 8, - salter_len = 64 }; - static const char * salter = "0123456789" - "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "./"; - - size_t i; - unsigned char salt[saltval_len]; - uint8_t sha[SHA_DIGEST_LENGTH]; - char buf[2*SHA_DIGEST_LENGTH + saltval_len + 2]; - - tr_rand_buffer (salt, saltval_len); - for (i=0; i