Commit 17882267 authored by tonu@volk.internalnet's avatar tonu@volk.internalnet
Browse files

--des-key-file functinality added

parent fb3d3e18
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -70,7 +70,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
			sql_update.cc sql_delete.cc uniques.cc \
			procedure.cc item_uniq.cc sql_test.cc \
			log.cc log_event.cc init.cc derror.cc sql_acl.cc \
			unireg.cc \
			unireg.cc des_key_file.cc \
			time.cc opt_range.cc opt_sum.cc opt_ft.cc \
		   	records.cc filesort.cc handler.cc \
		        ha_heap.cc ha_myisam.cc ha_myisammrg.cc \

sql/des_key_file.cc

0 → 100644
+86 −0
Original line number Diff line number Diff line
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult 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; either version 2 of the License, or
   (at your option) any later version.

   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <mysql_priv.h>

#ifdef HAVE_OPENSSL
/*
 Function which loads DES keys from plaintext file
 into memory on MySQL server startup and on command
 FLUSH DES_KEYS. Blame tonu@spam.ee on bugs ;)
*/
void 
load_des_key_file(const char *file_name)
{
  FILE *file;
  int ret=0;
  char offset;
  char buf[1024];
  des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  st_des_keyblock keyblock;
  DBUG_ENTER("load_des_key_file");
  VOID(pthread_mutex_lock(&LOCK_open));
  DBUG_PRINT("enter",("name: %s",file_name));
  if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
  {
    goto error_noclose;
  }
  while(!feof(file))
  {
    if ((my_fread(file, &offset, 1, MY_WME)) != 1)
      goto error_close;
    fgets(buf,sizeof(buf),file);
    int len=strlen(buf);
    if (len-->=1) 
      buf[len]='\0';
    /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
    offset-='0';
    if (offset >= 0 && offset <=9)
    {
      EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
        (uchar *)buf,
        strlen(buf),1,(uchar *)&keyblock,ivec);
      des_set_key_unchecked(&keyblock.key1,des_keyschedule[(int)offset].ks1);
      des_set_key_unchecked(&keyblock.key2,des_keyschedule[(int)offset].ks2);
      des_set_key_unchecked(&keyblock.key3,des_keyschedule[(int)offset].ks3);
    } 
    else
    {
      DBUG_PRINT("des",("wrong offset: %d",offset));
    }
  }
error_close:
  (void) my_fclose(file,MYF(MY_WME));
error_noclose:
  VOID(pthread_mutex_unlock(&LOCK_open));
  /* if (ret)
    do something; */
  DBUG_VOID_RETURN;
}

/* 
 This function is used to load right key with DES_ENCRYPT(text,integer)
*/
st_des_keyschedule *
des_key(int key)
{
  DBUG_ENTER("des_key");
  DBUG_PRINT("exit",("return: %x",&des_keyschedule[key]));
  DBUG_RETURN(&des_keyschedule[key]);
}

#endif /* HAVE_OPENSSL */
+58 −29
Original line number Diff line number Diff line
@@ -221,25 +221,32 @@ String *Item_func_des_encrypt::val_str(String *str)
{
  String *res  =args[0]->val_str(str);
#ifdef HAVE_OPENSSL
  des_key_schedule ks1, ks2, ks3;
  des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  struct {
	  des_cblock key1, key2, key3; // 8 bytes each
  } keyblock;
  struct st_des_keyblock keyblock;
  struct st_des_keyschedule keyschedule;
  struct st_des_keyschedule *keyschedule_ptr=&keyschedule;

  if ((null_value=args[0]->null_value))
    return 0;
  if (res->length() == 0)
    return &empty_string;
  if(res->c_ptr()[0]!='1') { // Skip encryption if already encrypted
  if(res->c_ptr()[0]!='1') // Skip encryption if already encrypted
  {
    if (args[1]->val_int())
    {
      keyschedule_ptr=des_key(args[1]->val_int());
    } 
    else
    {
      String *keystr=args[1]->val_str(&tmp_value);
      /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
      EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
	(uchar *)keystr->c_ptr(),
	(int)keystr->length(),1,(uchar *)&keyblock,ivec);
    des_set_key_unchecked(&keyblock.key1,ks1); // Here we set all 64-bit keys 
    des_set_key_unchecked(&keyblock.key2,ks2); // (56 effective) one by one
    des_set_key_unchecked(&keyblock.key3,ks3);
      des_set_key_unchecked(&keyblock.key1,keyschedule_ptr->ks1);
      des_set_key_unchecked(&keyblock.key2,keyschedule_ptr->ks2);
      des_set_key_unchecked(&keyblock.key3,keyschedule_ptr->ks3);
    }
    /* 
      The problem: DES algorithm requires original data to be in 8-bytes
      chunks. Missing bytes get filled with zeros and result of encryption 
@@ -252,10 +259,21 @@ String *Item_func_des_encrypt::val_str(String *str)
    for(int i=0 ; i < tail ; ++i) res->append('*');  
    res->append(tail);  		// Write tail length 0..7 to last pos
    str->length(res->length());
    for (uint j=0; j < res->length() ; ++j)
    {
	    DBUG_PRINT("info",("## res->c_ptr()[%d]='%c'",j,res->c_ptr()[j]));
    }
    des_ede3_cbc_encrypt(		// Real encryption
 	(const uchar*)(res->c_ptr()), 
	(uchar*)(str->c_ptr()), 
	res->length(), ks1, ks2, ks3, &ivec, TRUE);
	res->length(), 
	keyschedule_ptr->ks1, keyschedule_ptr->ks2, keyschedule_ptr->ks3, 
	&ivec, TRUE);
    for (uint j=0; j < res->length() ; ++j)
    {
	    DBUG_PRINT("info",("## str->c_ptr()[%d]='%c'",j,str->c_ptr()[j]));
    }

    res->set((const char*)"1",(uint)1); 
    for(uint i=0 ; i < str->length() ; ++i) 
    {
@@ -276,10 +294,9 @@ String *Item_func_des_decrypt::val_str(String *str)
#ifdef HAVE_OPENSSL
  des_key_schedule ks1, ks2, ks3;
  des_cblock ivec={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  struct {
	  des_cblock key1, key2, key3; // 8 bytes each
  } keyblock;

  struct st_des_keyblock keyblock;
  struct st_des_keyschedule keyschedule;
  struct st_des_keyschedule *keyschedule_ptr=&keyschedule;

  if ((null_value=args[0]->null_value))
    return 0;
@@ -295,23 +312,35 @@ String *Item_func_des_decrypt::val_str(String *str)
		      | (ascii_to_bin(res->c_ptr()[i+1]) << 5 ));
    }

    if (args[1]->val_int())
    {
      keyschedule_ptr=des_key(args[1]->val_int());
    } 
    else
    {
      /* 
       We make good 24-byte (168 bit) key 
       from given plaintext key with MD5 
      */
      String *keystr=args[1]->val_str(&tmp_value);
    int32 mode=0; 
    if(arg_count == 3 && !args[2]->null_value) 
      mode=args[2]->val_int();
    /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
      EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
	(uchar *)keystr->c_ptr(),
	(int)keystr->length(),1,(uchar *)&keyblock,ivec);
    des_set_key_unchecked(&keyblock.key1,ks1);	// Here we set all 64-bit keys 
    des_set_key_unchecked(&keyblock.key2,ks2);	// (56 effective) one by one
    des_set_key_unchecked(&keyblock.key3,ks3);
      /*
       Here we set all 64-bit keys (56 effective) one by one
      */
      des_set_key_unchecked(&keyblock.key1,keyschedule_ptr->ks1);
      des_set_key_unchecked(&keyblock.key2,keyschedule_ptr->ks2);
      des_set_key_unchecked(&keyblock.key3,keyschedule_ptr->ks3); 
    }
    res->length(str->length()); 

    des_ede3_cbc_encrypt(			// Real decryption
	(const uchar*)(str->c_ptr()), 
	(uchar*)(res->c_ptr()), 
	str->length(),                 
	ks1, ks2, ks3, &ivec, FALSE);
	keyschedule_ptr->ks1, keyschedule_ptr->ks2, keyschedule_ptr->ks3, 
	&ivec, FALSE);
    uchar tail=(res->c_ptr()[res->length()-1]) & 0x7;
    if ((res->length() > ((uint)1+tail)))   	// We should avoid negative length 
      res->length(res->length()-1-tail); 	// (can happen with wrong key)
+13 −0
Original line number Diff line number Diff line
@@ -396,6 +396,19 @@ void abort_locked_tables(THD *thd,const char *db, const char *table_name);
Field *find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables);
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
			   bool check_grant,bool allow_rowid);
#ifdef HAVE_OPENSSL
struct st_des_keyblock 
{ 
  des_cblock key1, key2, key3; 
};
struct st_des_keyschedule
{
  des_key_schedule ks1, ks2, ks3;
};
extern struct st_des_keyschedule des_keyschedule[10];
void load_des_key_file(const char *file_name);
struct st_des_keyschedule * des_key(int);
#endif /* HAVE_OPENSSL */

/* sql_list.c */
int mysqld_show_dbs(THD *thd,const char *wild);
+23 −4
Original line number Diff line number Diff line
@@ -242,6 +242,8 @@ static char glob_hostname[FN_REFLEN];

#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL
static char * des_key_file = 0;
struct st_des_keyschedule des_keyschedule[10];
struct st_VioSSLAcceptorFd * ssl_acceptor_fd = 0;
#endif /* HAVE_OPENSSL */

@@ -1749,6 +1751,10 @@ int main(int argc, char **argv)
      opt_use_ssl = 0;
    /* having ssl_acceptor_fd != 0 signals the use of SSL */
  }
  bzero(des_keyschedule,sizeof(struct st_des_keyschedule) * 10);
  DBUG_PRINT("des",("initializing %d bytes of %x",sizeof(struct st_des_keyschedule) * 10, des_keyschedule));
  if (des_key_file)
    load_des_key_file(des_key_file);
#endif /* HAVE_OPENSSL */

#ifdef HAVE_LIBWRAP
@@ -2669,7 +2675,8 @@ enum options {
	       OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
               OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT,
               OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
	       OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE
	       OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
	       OPT_DES_KEY_FILE
};

static struct option long_options[] = {
@@ -2697,6 +2704,7 @@ static struct option long_options[] = {
  {"character-sets-dir",    required_argument, 0, (int) OPT_CHARSETS_DIR},
  {"datadir",               required_argument, 0, 'h'},
  {"debug",                 optional_argument, 0, '#'},
  {"des-key-file",          required_argument, 0, (int) OPT_DES_KEY_FILE},
  {"default-character-set", required_argument, 0, 'C'},
  {"default-table-type",    required_argument, 0, (int) OPT_TABLE_TYPE},
  {"delay-key-write-for-all-tables",
@@ -3265,7 +3273,13 @@ static void usage(void)
			Set the default table type for tables\n\
  --delay-key-write-for-all-tables\n\
			Don't flush key buffers between writes for any MyISAM\n\
			table\n\
			table\n");
#ifdef HAVE_OPENSSL
  puts("\
  --des-key-file        Load keys for des_encrypt() and des_encrypt\n\
                        from given file");
#endif /* HAVE_OPENSSL */
  puts("\
  --enable-locking	Enable system locking\n\
  --enable-pstack	Print a symbolic stack trace on failure\n\
  -T, --exit-info	Used for debugging;  Use at your own risk!\n\
@@ -3892,6 +3906,11 @@ static void get_options(int argc,char **argv)
      charsets_dir = mysql_charsets_dir;
      break;
#include "sslopt-case.h"
#ifdef HAVE_OPENSSL
    case OPT_DES_KEY_FILE:
      des_key_file=optarg;
      break;
#endif
    case OPT_TX_ISOLATION:
    {
      int type;
Loading