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

Merge work.mysql.com:/home/bk/mysql-4.0

into volk.internalnet:/home/tonu/mysql-4.0
parents d3288575 a0d97110
Loading
Loading
Loading
Loading
+6.8 KiB

File added.

No diff preview for this file type.

+46 −0
Original line number Diff line number Diff line
-- source include/have_openssl.inc

use test;
drop  table if exists x;
create table x (x blob);
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('a','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','a'));
insert into x values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab'));
insert into x values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc'));
insert into x values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd'));
insert into x values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde'));
insert into x values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef'));
insert into x values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg'));
insert into x values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh'));
insert into x values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi'));
insert into x values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij'));
insert into x values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk'));
insert into x values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('red fox jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('fox jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('the lazy brown dog','sabakala'));
insert into x values (des_encrypt('lazy brown dog','sabakala'));
insert into x values (des_encrypt('brown dog','sabakala'));
insert into x values (des_encrypt('dog','sabakala'));
insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala'));
insert into x values (des_encrypt('jumped over the lazy brown dog','sabakala'));
select * from x;
select des_decrypt(x,'sabakala') from x;
#drop table x;

+74 −62
Original line number Diff line number Diff line
@@ -204,56 +204,65 @@ void Item_func_concat::fix_length_and_dec()
#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
#define ascii_to_bin(c) ((c)<=57 ? (c)-46 : (c)<=90 ? (c)-53 : (c)-59)

/* 
  Function des_encrypt() by tonu@spam.ee
  Works only if compiled with OpenSSL library support. 
  Output always starts with magic char "1" and all
  encrypted output is encoded into ASCII-protected
  container. 
  Original input is returned as output if input string 
  begins with magic "1". Credit card number always begin 
  with 4,5 or 6.
  Encryption result is longer than original by formula:
  new_length=(8-(original_length % 8))*2+1
*/

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};
  union {
	  des_cblock allkeys[3]; // 24 bytes (168 bits) total
  struct {
	  des_cblock key1, key2, key3; // 8 bytes each
  } key;
  } keyblock;

  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
    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_get_cipherbyname("DES-EDE3-CBC"),EVP_md5(),NULL,
    /* 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(),
	keystr->length(),1,(uchar *)&key.allkeys,ivec);
  // Here we set all 64-bit (56 actually) one by one
  des_set_key_unchecked(&key.key1,ks1);
  des_set_key_unchecked(&key.key2,ks2);
  des_set_key_unchecked(&key.key3,ks3);
  /* The problem: DES algorithm requires original data to be in 8-bytes
   * chunks. Missing bytes get filled with zeros and result of encryption 
   * can be up to 7 bytes longer than original string. When decrypted, 
   * we do not know the size of original string :(
   * We add one byte with value 0x0..0x7 to original plaintext marking
   * change of string length */
  uchar tail=8-(res->length() % 8);  // 1..8
  for(int i=0 ; i < (tail-1) ; ++i) res->append('*');  
  res->append(tail-1);  // Write tail length 0..7 to last pos
  // Real encryption 
  des_ede3_cbc_encrypt(
	(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);
    /* 
      The problem: DES algorithm requires original data to be in 8-bytes
      chunks. Missing bytes get filled with zeros and result of encryption 
      can be up to 7 bytes longer than original string. When decrypted, 
      we do not know the size of original string :(
      We add one byte with value 0x0..0x7 to original plaintext marking
      change of string length 
    */
    uchar tail=  7-( res->length() %8); // 0..7 marking real offsets 1..8
    for(int i=0 ; i < tail ; ++i) res->append('*');  
    res->append(tail);  		// Write tail length 0..7 to last pos
    str->length(res->length());
    des_ede3_cbc_encrypt(		// Real encryption
 	(const uchar*)(res->c_ptr()), 
	(uchar*)(res->c_ptr()), 
	(uchar*)(str->c_ptr()), 
	res->length(), ks1, ks2, ks3, &ivec, TRUE);
  if(mode) {
    // In case of ASCII mode we should convert binary string into ASCII
    str->set((const char*)0,(uint)0); 
    for(uint i=0 ; i < res->length() ; ++i) {
	str->append(bin_to_ascii((uchar)res->c_ptr()[i] & 0x3f)); 
        str->append(bin_to_ascii(((uchar)res->c_ptr()[i] >> 5 ) & 0x3f));
    res->set((const char*)"1",(uint)1); 
    for(uint i=0 ; i < str->length() ; ++i) 
    {
      res->append(bin_to_ascii((uchar)str->c_ptr()[i] & 0x3f)); 
      res->append(bin_to_ascii(((uchar)str->c_ptr()[i] >> 5 ) & 0x3f));
    } 
  }
    return str;
  } else
  return res;
#else
  null_value=1;
@@ -267,43 +276,46 @@ 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};
  union {
	  des_cblock allkeys[3]; // 24 bytes total
  struct {
	  des_cblock key1, key2, key3; // 8 bytes each
  } key;
  } keyblock;


  if ((null_value=args[0]->null_value))
    return 0;
  if (res->length() == 0)
    return &empty_string;
  
  if(res->c_ptr()[0]=='1') // Skip decryption if not encrypted
  {
    str->set((const char*)0,(uint)0); 
    for(uint i=1 ; i < res->length() ; i+=2) 
    {
      str->append((ascii_to_bin(res->c_ptr()[i])) 
		      | (ascii_to_bin(res->c_ptr()[i+1]) << 5 ));
    }
 
    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_get_cipherbyname("DES-EDE3-CBC"),EVP_md5(),NULL,
    /* 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(),
	keystr->length(),1,(uchar *)&key.allkeys,ivec);
  // Here we set all 64-bit keys (56 effective) one by one
  des_set_key_unchecked(&key.key1,ks1);
  des_set_key_unchecked(&key.key2,ks2);
  des_set_key_unchecked(&key.key3,ks3);
  str->set((const char*)0,(uint)0); 
  if(mode) {
    for(uint i=0 ; i < res->length() ; i+=2) {
      str->append((ascii_to_bin(res->c_ptr()[i])) 
		| (ascii_to_bin(res->c_ptr()[i+1]) << 5 ));
    }
  } else
    str->copy(res->c_ptr());
  // Real decryption 
  des_ede3_cbc_encrypt(
	(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);
    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);
  uchar tail=(res->c_ptr()[str->length()-1]) & 0x7;
  res->length(str->length()-tail-1);
    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)
  }
  return res;
#else
  null_value=1;
+2 −2
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ class Item_func_des_encrypt :public Item_str_func
  Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
  Item_func_des_encrypt(Item *a, Item *b, Item *c): Item_str_func(a,b,c) {}
  String *val_str(String *);
  void fix_length_and_dec() { maybe_null=1; max_length = 13; }
  void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; }
  const char *func_name() const { return "des_encrypt"; }
};

@@ -242,7 +242,7 @@ class Item_func_des_decrypt :public Item_str_func
  Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {}
  Item_func_des_decrypt(Item *a, Item *b, Item *c): Item_str_func(a,b,c) {}
  String *val_str(String *);
  void fix_length_and_dec() { maybe_null=1; max_length = 13; }
  void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; }
  const char *func_name() const { return "des_decrypt"; }
};