#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}.
This commit is contained in:
Mike Gelfand 2014-12-04 20:45:18 +00:00
parent 5c43b5c23c
commit 748f8a75d2
4 changed files with 79 additions and 80 deletions

View File

@ -10,7 +10,7 @@
#include <assert.h>
#include <stdarg.h>
#include <stdlib.h> /* abs (), srand (), rand () */
#include <string.h> /* memmove (), memset (), strlen () */
#include <string.h> /* 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,

View File

@ -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 ()

View File

@ -8,7 +8,7 @@
*/
#include <assert.h>
#include <string.h> /* memcpy (), memmove (), memset (), strcmp () */
#include <string.h> /* 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<saltval_len; ++i)
salt[i] = salter[ salt[i] % salter_len ];
tr_sha1 (sha, plaintext, strlen (plaintext), salt, 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 * source, const char * pass)
{
char * salt;
size_t saltlen;
char * hashed;
uint8_t buf[SHA_DIGEST_LENGTH];
bool result;
const size_t sourcelen = strlen (source);
/* 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, source + 2*SHA_DIGEST_LENGTH+1, saltlen);
/* hash pass + salt */
hashed = tr_malloc (2*SHA_DIGEST_LENGTH + saltlen + 2);
tr_sha1 (buf, pass, strlen (pass), salt, saltlen, NULL);
tr_sha1_to_hex (&hashed[1], buf);
memcpy (hashed + 1+2*SHA_DIGEST_LENGTH, salt, saltlen);
hashed[1+2*SHA_DIGEST_LENGTH + saltlen] = '\0';
hashed[0] = '{';
result = strcmp (source, hashed) == 0 ? true : false;
tr_free (hashed);
tr_free (salt);
return result;
}

View File

@ -85,17 +85,4 @@ bool tr_cryptoSecretKeySha1 (const tr_crypto * crypto,
/* @} */
/**
*** @addtogroup utils Utilities
*** @{
**/
/** @brief generate a SSHA password from its plaintext source */
char* tr_ssha1 (const void * plaintext);
/** @brief Validate a test password against the a ssha1 password */
bool tr_ssha1_matches (const char * ssha1, const char * pass);
/* @} */
#endif