Commit bd1139ad authored by Sergei Golubchik's avatar Sergei Golubchik

cleanup: generalize my_sha1.cc

move most of the code into my_sha.ic, making it independent
from the actual SHAx variant.
parent 6cddd12a
#ifndef SHA1_INCLUDED
#define SHA1_INCLUDED
/* Copyright (c) 2013, Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <mysql/service_sha1.h>
#define SHA1_HASH_SIZE MY_SHA1_HASH_SIZE
#define compute_sha1_hash(A,B,C) my_sha1(A,B,C)
#define compute_sha1_hash_multi(A,B,C,D,E) my_sha1_multi(A,B,C,D,E,NULL)
#endif /* SHA__INCLUDED */
/* Copyright (c) 2012, Oracle and/or its affiliates.
Copyright (c) 2014, 2017, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
/**
@file
@brief
Wrapper functions for OpenSSL, YaSSL implementations. Also provides a
Compatibility layer to make available YaSSL's SHAn implementation.
*/
#include <my_global.h>
#include <stdarg.h>
#define HASH_SIZE 20
#if defined(HAVE_YASSL)
#include "sha.hpp"
#define xCONTEXT(x) TaoCrypt::SHA ## x
#define yCONTEXT(y) xCONTEXT(y)
#define CONTEXT yCONTEXT(NUM)
#define SHA1 SHA
static void sha_init(CONTEXT *context)
{
context->Init();
}
/*
this is a variant of sha_init to be used in this file only.
does nothing for yassl, because the context's constructor was called automatically.
*/
static void sha_init_fast(CONTEXT *context)
{
}
static void sha_input(CONTEXT *context, const uchar *buf, unsigned len)
{
context->Update((const TaoCrypt::byte *) buf, len);
}
static void sha_result(CONTEXT *context, uchar digest[HASH_SIZE])
{
context->Final((TaoCrypt::byte *) digest);
}
#elif defined(HAVE_OPENSSL)
#include <openssl/sha.h>
#define xCONTEXT(x) SHA ## x ## _CTX
#define yCONTEXT(y) xCONTEXT(y)
#define CONTEXT yCONTEXT(NUM)
#define SHA1_CTX SHA_CTX
#define xSHA_Init(x) SHA ## x ## _Init
#define xSHA_Update(x) SHA ## x ## _Update
#define xSHA_Final(x) SHA ## x ## _Final
#define ySHA_Init(y) xSHA_Init(y)
#define ySHA_Update(y) xSHA_Update(y)
#define ySHA_Final(y) xSHA_Final(y)
#define SHA_Init ySHA_Init(NUM)
#define SHA_Update ySHA_Update(NUM)
#define SHA_Final ySHA_Final(NUM)
static void sha_init(CONTEXT *context)
{
SHA_Init(context);
}
static void sha_init_fast(CONTEXT *context)
{
sha_init(context);
}
static void sha_input(CONTEXT *context, const uchar *buf, unsigned len)
{
SHA_Update(context, buf, len);
}
static void sha_result(CONTEXT *context, uchar digest[HASH_SIZE])
{
SHA_Final(digest, context);
}
#endif /* HAVE_YASSL */
#define xmy_sha_multi(x) my_sha ## x ## _multi
#define xmy_sha_context_size(x) my_sha ## x ## _context_size
#define xmy_sha_init(x) my_sha ## x ## _init
#define xmy_sha_input(x) my_sha ## x ## _input
#define xmy_sha_result(x) my_sha ## x ## _result
#define xmy_sha(x) my_sha ## x
#define ymy_sha_multi(y) xmy_sha_multi(y)
#define ymy_sha_context_size(y) xmy_sha_context_size(y)
#define ymy_sha_init(y) xmy_sha_init(y)
#define ymy_sha_input(y) xmy_sha_input(y)
#define ymy_sha_result(y) xmy_sha_result(y)
#define ymy_sha(y) xmy_sha(y)
#define my_sha_multi ymy_sha_multi(NUM)
#define my_sha_context_size ymy_sha_context_size(NUM)
#define my_sha_init ymy_sha_init(NUM)
#define my_sha_input ymy_sha_input(NUM)
#define my_sha_result ymy_sha_result(NUM)
#define my_sha ymy_sha(NUM)
/**
Wrapper function to compute SHAn message digest.
@param digest [out] Computed SHAn digest
@param buf [in] Message to be computed
@param len [in] Length of the message
@return void
*/
void my_sha(uchar *digest, const char *buf, size_t len)
{
CONTEXT context;
sha_init_fast(&context);
sha_input(&context, (const uchar *)buf, len);
sha_result(&context, digest);
}
/**
Wrapper function to compute SHAn message digest for
two messages in order to emulate shaN(msg1, msg2).
@param digest [out] Computed SHAn digest
@param buf1 [in] First message
@param len1 [in] Length of first message
@param buf2 [in] Second message
@param len2 [in] Length of second message
@return void
*/
void my_sha_multi(uchar *digest, ...)
{
va_list args;
va_start(args, digest);
CONTEXT context;
const uchar *str;
sha_init_fast(&context);
for (str= va_arg(args, const uchar*); str; str= va_arg(args, const uchar*))
sha_input(&context, str, va_arg(args, size_t));
sha_result(&context, digest);
va_end(args);
}
size_t my_sha_context_size()
{
return sizeof(CONTEXT);
}
void my_sha_init(void *context)
{
sha_init((CONTEXT *)context);
}
void my_sha_input(void *context, const uchar *buf, size_t len)
{
sha_input((CONTEXT *)context, buf, len);
}
void my_sha_result(void *context, uchar *digest)
{
sha_result((CONTEXT *)context, digest);
}
/* Copyright (c) 2012, Oracle and/or its affiliates. /* Copyright (c) 2017, MariaDB
Copyright (c) 2014, SkySQL Ab.
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
...@@ -14,135 +13,6 @@ ...@@ -14,135 +13,6 @@
along with this program; if not, write to the Free Software Foundation, along with this program; if not, write to the Free Software Foundation,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
#define NUM 1
/** #include "my_sha.ic"
@file
@brief
Wrapper functions for OpenSSL, YaSSL implementations. Also provides a
Compatibility layer to make available YaSSL's SHA1 implementation.
*/
#include <my_global.h>
#include <sha1.h>
#include <stdarg.h>
#if defined(HAVE_YASSL)
#include "sha.hpp"
typedef TaoCrypt::SHA SHA_CTX;
static void sha1_init(SHA_CTX *context)
{
context->Init();
}
/*
this is a variant of sha1_init to be used in this file only.
does nothing for yassl, because the context's constructor was called automatically.
*/
static void sha1_init_fast(SHA_CTX *context)
{
}
static void sha1_input(SHA_CTX *context, const uchar *buf, unsigned len)
{
context->Update((const TaoCrypt::byte *) buf, len);
}
static void sha1_result(SHA_CTX *context, uchar digest[SHA1_HASH_SIZE])
{
context->Final((TaoCrypt::byte *) digest);
}
#elif defined(HAVE_OPENSSL)
#include <openssl/sha.h>
static void sha1_init(SHA_CTX *context)
{
SHA1_Init(context);
}
static void sha1_init_fast(SHA_CTX *context)
{
sha1_init(context);
}
static void sha1_input(SHA_CTX *context, const uchar *buf, unsigned len)
{
SHA1_Update(context, buf, len);
}
static void sha1_result(SHA_CTX *context, uchar digest[SHA1_HASH_SIZE])
{
SHA1_Final(digest, context);
}
#endif /* HAVE_YASSL */
/**
Wrapper function to compute SHA1 message digest.
@param digest [out] Computed SHA1 digest
@param buf [in] Message to be computed
@param len [in] Length of the message
@return void
*/
void my_sha1(uchar *digest, const char *buf, size_t len)
{
SHA_CTX sha1_context;
sha1_init_fast(&sha1_context);
sha1_input(&sha1_context, (const uchar *)buf, len);
sha1_result(&sha1_context, digest);
}
/**
Wrapper function to compute SHA1 message digest for
two messages in order to emulate sha1(msg1, msg2).
@param digest [out] Computed SHA1 digest
@param buf1 [in] First message
@param len1 [in] Length of first message
@param buf2 [in] Second message
@param len2 [in] Length of second message
@return void
*/
void my_sha1_multi(uchar *digest, ...)
{
va_list args;
va_start(args, digest);
SHA_CTX sha1_context;
const uchar *str;
sha1_init_fast(&sha1_context);
for (str= va_arg(args, const uchar*); str; str= va_arg(args, const uchar*))
sha1_input(&sha1_context, str, va_arg(args, size_t));
sha1_result(&sha1_context, digest);
va_end(args);
}
size_t my_sha1_context_size()
{
return sizeof(SHA_CTX);
}
void my_sha1_init(void *context)
{
sha1_init((SHA_CTX *)context);
}
void my_sha1_input(void *context, const uchar *buf, size_t len)
{
sha1_input((SHA_CTX *)context, buf, len);
}
void my_sha1_result(void *context, uchar *digest)
{
sha1_result((SHA_CTX *)context, digest);
}
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#endif #endif
#include <base64.h> #include <base64.h>
#include <sha1.h>
#if defined (_WIN32) #if defined (_WIN32)
#define HAVE_SYS_UTSNAME_H #define HAVE_SYS_UTSNAME_H
...@@ -420,7 +419,7 @@ int fill_collation_statistics(THD *thd, TABLE_LIST *tables) ...@@ -420,7 +419,7 @@ int fill_collation_statistics(THD *thd, TABLE_LIST *tables)
int calculate_server_uid(char *dest) int calculate_server_uid(char *dest)
{ {
uchar rawbuf[2 + 6]; uchar rawbuf[2 + 6];
uchar shabuf[SHA1_HASH_SIZE]; uchar shabuf[MY_SHA1_HASH_SIZE];
int2store(rawbuf, mysqld_port); int2store(rawbuf, mysqld_port);
if (my_gethwaddr(rawbuf + 2)) if (my_gethwaddr(rawbuf + 2))
...@@ -429,7 +428,7 @@ int calculate_server_uid(char *dest) ...@@ -429,7 +428,7 @@ int calculate_server_uid(char *dest)
return 1; return 1;
} }
compute_sha1_hash((uint8*) shabuf, (char*) rawbuf, sizeof(rawbuf)); my_sha1((uint8*) shabuf, (char*) rawbuf, sizeof(rawbuf));
assert(base64_needed_encoded_length(sizeof(shabuf)) <= SERVER_UID_SIZE); assert(base64_needed_encoded_length(sizeof(shabuf)) <= SERVER_UID_SIZE);
base64_encode(shabuf, sizeof(shabuf), dest); base64_encode(shabuf, sizeof(shabuf), dest);
......
...@@ -53,7 +53,6 @@ ...@@ -53,7 +53,6 @@
#include <m_ctype.h> #include <m_ctype.h>
#include <base64.h> #include <base64.h>
#include <my_md5.h> #include <my_md5.h>
#include "sha1.h"
#include <zlib.h> #include <zlib.h>
C_MODE_START C_MODE_START
#include "../mysys/my_static.h" // For soundex_map #include "../mysys/my_static.h" // For soundex_map
...@@ -172,14 +171,14 @@ String *Item_func_sha::val_str_ascii(String *str) ...@@ -172,14 +171,14 @@ String *Item_func_sha::val_str_ascii(String *str)
if (sptr) /* If we got value different from NULL */ if (sptr) /* If we got value different from NULL */
{ {
/* Temporary buffer to store 160bit digest */ /* Temporary buffer to store 160bit digest */
uint8 digest[SHA1_HASH_SIZE]; uint8 digest[MY_SHA1_HASH_SIZE];
compute_sha1_hash(digest, (const char *) sptr->ptr(), sptr->length()); my_sha1(digest, (const char *) sptr->ptr(), sptr->length());
/* Ensure that memory is free and we got result */ /* Ensure that memory is free and we got result */
if (!str->alloc(SHA1_HASH_SIZE*2)) if (!str->alloc(MY_SHA1_HASH_SIZE*2))
{ {
array_to_hex((char *) str->ptr(), digest, SHA1_HASH_SIZE); array_to_hex((char *) str->ptr(), digest, MY_SHA1_HASH_SIZE);
str->set_charset(&my_charset_numeric); str->set_charset(&my_charset_numeric);
str->length((uint) SHA1_HASH_SIZE*2); str->length((uint) MY_SHA1_HASH_SIZE*2);
null_value=0; null_value=0;
return str; return str;
} }
...@@ -191,7 +190,7 @@ String *Item_func_sha::val_str_ascii(String *str) ...@@ -191,7 +190,7 @@ String *Item_func_sha::val_str_ascii(String *str)
void Item_func_sha::fix_length_and_dec() void Item_func_sha::fix_length_and_dec()
{ {
// size of hex representation of hash // size of hex representation of hash
fix_length_and_charset(SHA1_HASH_SIZE * 2, default_charset()); fix_length_and_charset(MY_SHA1_HASH_SIZE * 2, default_charset());
} }
String *Item_func_sha2::val_str_ascii(String *str) String *Item_func_sha2::val_str_ascii(String *str)
......
...@@ -66,7 +66,6 @@ ...@@ -66,7 +66,6 @@
#include <password.h> #include <password.h>
#include <mysql.h> #include <mysql.h>
#include <my_rnd.h> #include <my_rnd.h>
#include <sha1.h>
/************ MySQL 3.23-4.0 authentication routines: untouched ***********/ /************ MySQL 3.23-4.0 authentication routines: untouched ***********/
...@@ -389,10 +388,10 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len, ...@@ -389,10 +388,10 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len,
uint8 *hash_stage1, uint8 *hash_stage2) uint8 *hash_stage1, uint8 *hash_stage2)
{ {
/* Stage 1: hash password */ /* Stage 1: hash password */
compute_sha1_hash(hash_stage1, password, pass_len); my_sha1(hash_stage1, password, pass_len);
/* Stage 2 : hash first stage's output. */ /* Stage 2 : hash first stage's output. */
compute_sha1_hash(hash_stage2, (const char *) hash_stage1, SHA1_HASH_SIZE); my_sha1(hash_stage2, (const char *) hash_stage1, MY_SHA1_HASH_SIZE);
} }
...@@ -404,7 +403,7 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len, ...@@ -404,7 +403,7 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len,
is stored in the database. is stored in the database.
SYNOPSIS SYNOPSIS
my_make_scrambled_password() my_make_scrambled_password()
buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string buf OUT buffer of size 2*MY_SHA1_HASH_SIZE + 2 to store hex string
password IN password string password IN password string
pass_len IN length of password string pass_len IN length of password string
*/ */
...@@ -412,14 +411,14 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len, ...@@ -412,14 +411,14 @@ void compute_two_stage_sha1_hash(const char *password, size_t pass_len,
void my_make_scrambled_password(char *to, const char *password, void my_make_scrambled_password(char *to, const char *password,
size_t pass_len) size_t pass_len)
{ {
uint8 hash_stage2[SHA1_HASH_SIZE]; uint8 hash_stage2[MY_SHA1_HASH_SIZE];
/* Two stage SHA1 hash of the password. */ /* Two stage SHA1 hash of the password. */
compute_two_stage_sha1_hash(password, pass_len, (uint8 *) to, hash_stage2); compute_two_stage_sha1_hash(password, pass_len, (uint8 *) to, hash_stage2);
/* convert hash_stage2 to hex string */ /* convert hash_stage2 to hex string */
*to++= PVERSION41_CHAR; *to++= PVERSION41_CHAR;
octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE); octet2hex(to, (const char*) hash_stage2, MY_SHA1_HASH_SIZE);
} }
...@@ -430,7 +429,7 @@ void my_make_scrambled_password(char *to, const char *password, ...@@ -430,7 +429,7 @@ void my_make_scrambled_password(char *to, const char *password,
avoid strlen(). avoid strlen().
SYNOPSIS SYNOPSIS
make_scrambled_password() make_scrambled_password()
buf OUT buffer of size 2*SHA1_HASH_SIZE + 2 to store hex string buf OUT buffer of size 2*MY_SHA1_HASH_SIZE + 2 to store hex string
password IN NULL-terminated password string password IN NULL-terminated password string
*/ */
...@@ -451,7 +450,7 @@ void make_scrambled_password(char *to, const char *password) ...@@ -451,7 +450,7 @@ void make_scrambled_password(char *to, const char *password)
SYNOPSIS SYNOPSIS
scramble() scramble()
buf OUT store scrambled string here. The buf must be at least buf OUT store scrambled string here. The buf must be at least
SHA1_HASH_SIZE bytes long. MY_SHA1_HASH_SIZE bytes long.
message IN random message, must be exactly SCRAMBLE_LENGTH long and message IN random message, must be exactly SCRAMBLE_LENGTH long and
NULL-terminated. NULL-terminated.
password IN users' password password IN users' password
...@@ -460,16 +459,16 @@ void make_scrambled_password(char *to, const char *password) ...@@ -460,16 +459,16 @@ void make_scrambled_password(char *to, const char *password)
void void
scramble(char *to, const char *message, const char *password) scramble(char *to, const char *message, const char *password)
{ {
uint8 hash_stage1[SHA1_HASH_SIZE]; uint8 hash_stage1[MY_SHA1_HASH_SIZE];
uint8 hash_stage2[SHA1_HASH_SIZE]; uint8 hash_stage2[MY_SHA1_HASH_SIZE];
/* Two stage SHA1 hash of the password. */ /* Two stage SHA1 hash of the password. */
compute_two_stage_sha1_hash(password, strlen(password), hash_stage1, compute_two_stage_sha1_hash(password, strlen(password), hash_stage1,
hash_stage2); hash_stage2);
/* create crypt string as sha1(message, hash_stage2) */; /* create crypt string as sha1(message, hash_stage2) */;
compute_sha1_hash_multi((uint8 *) to, message, SCRAMBLE_LENGTH, my_sha1_multi((uint8 *) to, message, SCRAMBLE_LENGTH,
(const char *) hash_stage2, SHA1_HASH_SIZE); (const char *) hash_stage2, MY_SHA1_HASH_SIZE, NULL);
my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH); my_crypt(to, (const uchar *) to, hash_stage1, SCRAMBLE_LENGTH);
} }
...@@ -478,7 +477,7 @@ scramble(char *to, const char *message, const char *password) ...@@ -478,7 +477,7 @@ scramble(char *to, const char *message, const char *password)
Check that scrambled message corresponds to the password; the function Check that scrambled message corresponds to the password; the function
is used by server to check that received reply is authentic. is used by server to check that received reply is authentic.
This function does not check lengths of given strings: message must be This function does not check lengths of given strings: message must be
null-terminated, reply and hash_stage2 must be at least SHA1_HASH_SIZE null-terminated, reply and hash_stage2 must be at least MY_SHA1_HASH_SIZE
long (if not, something fishy is going on). long (if not, something fishy is going on).
SYNOPSIS SYNOPSIS
check_scramble() check_scramble()
...@@ -498,19 +497,19 @@ my_bool ...@@ -498,19 +497,19 @@ my_bool
check_scramble(const uchar *scramble_arg, const char *message, check_scramble(const uchar *scramble_arg, const char *message,
const uint8 *hash_stage2) const uint8 *hash_stage2)
{ {
uint8 buf[SHA1_HASH_SIZE]; uint8 buf[MY_SHA1_HASH_SIZE];
uint8 hash_stage2_reassured[SHA1_HASH_SIZE]; uint8 hash_stage2_reassured[MY_SHA1_HASH_SIZE];
/* create key to encrypt scramble */ /* create key to encrypt scramble */
compute_sha1_hash_multi(buf, message, SCRAMBLE_LENGTH, my_sha1_multi(buf, message, SCRAMBLE_LENGTH,
(const char *) hash_stage2, SHA1_HASH_SIZE); (const char *) hash_stage2, MY_SHA1_HASH_SIZE, NULL);
/* encrypt scramble */ /* encrypt scramble */
my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH); my_crypt((char *) buf, buf, scramble_arg, SCRAMBLE_LENGTH);
/* now buf supposedly contains hash_stage1: so we can get hash_stage2 */ /* now buf supposedly contains hash_stage1: so we can get hash_stage2 */
compute_sha1_hash(hash_stage2_reassured, (const char *) buf, SHA1_HASH_SIZE); my_sha1(hash_stage2_reassured, (const char *) buf, MY_SHA1_HASH_SIZE);
return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE)); return MY_TEST(memcmp(hash_stage2, hash_stage2_reassured, MY_SHA1_HASH_SIZE));
} }
/* /*
...@@ -518,27 +517,27 @@ check_scramble(const uchar *scramble_arg, const char *message, ...@@ -518,27 +517,27 @@ check_scramble(const uchar *scramble_arg, const char *message,
SYNOPSIS SYNOPSIS
get_salt_from_password() get_salt_from_password()
res OUT buf to hold password. Must be at least SHA1_HASH_SIZE res OUT buf to hold password. Must be at least MY_SHA1_HASH_SIZE
bytes long. bytes long.
password IN 4.1.1 version value of user.password password IN 4.1.1 version value of user.password
*/ */
void get_salt_from_password(uint8 *hash_stage2, const char *password) void get_salt_from_password(uint8 *hash_stage2, const char *password)
{ {
hex2octet(hash_stage2, password+1 /* skip '*' */, SHA1_HASH_SIZE * 2); hex2octet(hash_stage2, password+1 /* skip '*' */, MY_SHA1_HASH_SIZE * 2);
} }
/* /*
Convert scrambled password from binary form to asciiz hex string. Convert scrambled password from binary form to asciiz hex string.
SYNOPSIS SYNOPSIS
make_password_from_salt() make_password_from_salt()
to OUT store resulting string here, 2*SHA1_HASH_SIZE+2 bytes to OUT store resulting string here, 2*MY_SHA1_HASH_SIZE+2 bytes
salt IN password in salt format salt IN password in salt format
*/ */
void make_password_from_salt(char *to, const uint8 *hash_stage2) void make_password_from_salt(char *to, const uint8 *hash_stage2)
{ {
*to++= PVERSION41_CHAR; *to++= PVERSION41_CHAR;
octet2hex(to, (const char*) hash_stage2, SHA1_HASH_SIZE); octet2hex(to, (const char*) hash_stage2, MY_SHA1_HASH_SIZE);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment