1/* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
15
16#include "mariadb.h" // HAVE_*
17#include "sql_priv.h"
18#include "des_key_file.h" // st_des_keyschedule, st_des_keyblock
19#include "log.h" // sql_print_error
20#include <m_ctype.h>
21
22#ifdef HAVE_OPENSSL
23
24struct st_des_keyschedule des_keyschedule[10];
25uint des_default_key;
26
27#define des_cs &my_charset_latin1
28
29/**
30 Load DES keys from plaintext file into
31 memory on MySQL server startup and on command FLUSH DES_KEY_FILE.
32
33 @retval
34 0 ok
35 @retval
36 1 Error
37*/
38
39
40bool
41load_des_key_file(const char *file_name)
42{
43 bool result=1;
44 File file;
45 IO_CACHE io;
46 DBUG_ENTER("load_des_key_file");
47 DBUG_PRINT("enter",("name: %s",file_name));
48
49 mysql_mutex_lock(&LOCK_des_key_file);
50 if ((file= mysql_file_open(key_file_des_key_file, file_name,
51 O_RDONLY | O_BINARY, MYF(MY_WME))) < 0 ||
52 init_io_cache(&io, file, IO_SIZE*2, READ_CACHE, 0, 0, MYF(MY_WME)))
53 goto error;
54
55 bzero((char*) des_keyschedule,sizeof(struct st_des_keyschedule) * 10);
56 des_default_key=15; // Impossible key
57 for (;;)
58 {
59 char *start, *end;
60 char buf[1024], offset;
61 st_des_keyblock keyblock;
62 size_t length;
63
64 if (!(length=my_b_gets(&io,buf,sizeof(buf)-1)))
65 break; // End of file
66 offset=buf[0];
67 if (offset >= '0' && offset <= '9') // If ok key
68 {
69 offset=(char) (offset - '0');
70 // Remove newline and possible other control characters
71 for (start=buf+1 ; my_isspace(des_cs, *start) ; start++) ;
72 end=buf+length;
73 for (end=strend(buf) ;
74 end > start && !my_isgraph(des_cs, end[-1]) ; end--) ;
75
76 if (start != end)
77 {
78 DES_cblock ivec;
79 bzero((char*) &ivec,sizeof(ivec));
80 // We make good 24-byte (168 bit) key from given plaintext key with MD5
81 EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
82 (uchar *) start, (int) (end-start),1,
83 (uchar *) &keyblock,
84 ivec);
85 DES_set_key_unchecked(&keyblock.key1,&(des_keyschedule[(int)offset].ks1));
86 DES_set_key_unchecked(&keyblock.key2,&(des_keyschedule[(int)offset].ks2));
87 DES_set_key_unchecked(&keyblock.key3,&(des_keyschedule[(int)offset].ks3));
88 if (des_default_key == 15)
89 des_default_key= (uint) offset; // use first as def.
90 }
91 }
92 else if (offset != '#')
93 sql_print_error("load_des_file: Found wrong key_number: %c",offset);
94 }
95 result=0;
96
97error:
98 if (file >= 0)
99 {
100 mysql_file_close(file, MYF(0));
101 end_io_cache(&io);
102 }
103 mysql_mutex_unlock(&LOCK_des_key_file);
104 DBUG_RETURN(result);
105}
106#endif /* HAVE_OPENSSL */
107