diff --git a/aes/create_keys.c b/aes/create_keys.c index bc338639c..760ee96b3 100755 --- a/aes/create_keys.c +++ b/aes/create_keys.c @@ -1,31 +1,9 @@ -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAXSCALE_SECRETS_ONE 4 -#define MAXSCALE_SECRETS_TWO 28 -#define MAXSCALE_SECRETS_INIT_VAL_ONE 11 -#define MAXSCALE_SECRETS_INIT_VAL_TWO 5 +#include "secrets.h" int main(int argc, char *argv[]) { - char secret_buffer[1 + AES_BLOCK_SIZE * 3 + 3] = ""; - char scramble_secret[1 + AES_BLOCK_SIZE * 3 + 3] = ""; - char enc_key[1 + AES_BLOCK_SIZE * 2]=""; - char iv[1 + AES_BLOCK_SIZE]=""; - char *home =NULL; - - char one_byte[1 + 1]=""; - char two_bytes[1 + 2]=""; - char secret_file[1024]=""; - int fd =0; + char *home = NULL; if ((home = getenv("MAXSCALE_HOME")) != NULL) { sprintf(secret_file, "%s/secrets.key", home); @@ -33,48 +11,9 @@ int main(int argc, char *argv[]) strcpy(secret_file, "./secrets.key"); } - fd = open(secret_file, O_CREAT | O_WRONLY | O_TRUNC); - - if (fd < 0) { - fprintf(stderr, "%s, failed opening secret file [%s]. Error %i, %s\n", argv[0], secret_file, errno, strerror(errno)); - exit(1); - - } - - srand(time(NULL)); - gw_generate_random_str(secret_buffer, AES_BLOCK_SIZE * 3 + 3); - - memcpy(one_byte, secret_buffer, 1); - memcpy(enc_key, secret_buffer + 1, AES_BLOCK_SIZE * 2); - memcpy(iv, secret_buffer + 1 + AES_BLOCK_SIZE * 2, AES_BLOCK_SIZE); - memcpy(two_bytes, secret_buffer + 1 + AES_BLOCK_SIZE * 2 + AES_BLOCK_SIZE + 1, 2); - - //fprintf(stderr, "<<< Key32 is [%s]\n", enc_key); - //fprintf(stderr, "<<< IV16 is [%s]\n", iv); - - memcpy(scramble_secret, one_byte, 1); - - memcpy(scramble_secret + 1, enc_key, MAXSCALE_SECRETS_ONE); - - memcpy(scramble_secret + 1 + MAXSCALE_SECRETS_ONE, iv, MAXSCALE_SECRETS_INIT_VAL_ONE); - - memcpy(scramble_secret + 1 + MAXSCALE_SECRETS_ONE + MAXSCALE_SECRETS_INIT_VAL_ONE, enc_key + MAXSCALE_SECRETS_ONE, MAXSCALE_SECRETS_TWO); - - memcpy(scramble_secret + 1 + MAXSCALE_SECRETS_ONE + MAXSCALE_SECRETS_INIT_VAL_ONE + MAXSCALE_SECRETS_TWO, iv + MAXSCALE_SECRETS_INIT_VAL_ONE, MAXSCALE_SECRETS_INIT_VAL_TWO); - - memcpy(scramble_secret + 1 + MAXSCALE_SECRETS_ONE + MAXSCALE_SECRETS_INIT_VAL_ONE + MAXSCALE_SECRETS_TWO + MAXSCALE_SECRETS_INIT_VAL_TWO, two_bytes, 2); - - - if(write(fd, scramble_secret, sizeof(scramble_secret)-1) < 0) { - fprintf(stderr, "%s, failed writing into secret file [%s]. Error %i, %s\n", argv[0], secret_file, errno, strerror(errno)); - exit(1); - } + secrets_writeKeys(secret_file); fprintf(stderr, "MaxScale secret keys initialized in %s\n", secret_file); - if (close(fd) < 0) { - fprintf(stderr, "%s, failed closing the secret file [%s]. Error %i, %s\n", argv[0], secret_file, errno, strerror(errno)); - } - exit(0); } diff --git a/aes/read_keys.c b/aes/read_keys.c index 8632a53d9..9ada3a3cc 100755 --- a/aes/read_keys.c +++ b/aes/read_keys.c @@ -1,32 +1,12 @@ -#include -#include -#include -#include -#include -#include -#include - -#include - -#define MAXSCALE_SECRETS_ONE 4 -#define MAXSCALE_SECRETS_TWO 28 -#define MAXSCALE_SECRETS_INIT_VAL_ONE 11 -#define MAXSCALE_SECRETS_INIT_VAL_TWO 5 +#include "secrets.h" int main(int argc, char *argv[]) { char enc_key[1 + AES_BLOCK_SIZE * 2]=""; char iv[1 + AES_BLOCK_SIZE]=""; char *home =NULL; - struct stat secret_stats; - char read_buffer[1 + AES_BLOCK_SIZE * 2 + AES_BLOCK_SIZE + 3]=""; - - char one_byte[1]=""; - char two_bytes[2]=""; char secret_file[1024]=""; - int fd =0; - int secret_file_size = 0; if ((home = getenv("MAXSCALE_HOME")) != NULL) { sprintf(secret_file, "%s/secrets.key", home); @@ -34,40 +14,11 @@ int main(int argc, char *argv[]) strcpy(secret_file, "./secrets.key"); } - fd = open(secret_file, O_RDONLY); - - if (fd < 0) { - fprintf(stderr, "%s, failed opening secret file [%s]. Error %i, %s\n", argv[0], secret_file, errno, strerror(errno)); - - } - - if (fstat(fd, &secret_stats) < 0) { - fprintf(stderr, "%s, failed accessing secret file details [%s]. Error %i, %s\n", argv[0], secret_file, errno, strerror(errno)); - } - - secret_file_size = secret_stats.st_size; - - fprintf(stderr, "The secret file has %i bytes\n", secret_file_size); - - if (read(fd, read_buffer, sizeof(read_buffer)-1) < 0) { - fprintf(stderr, "%s, failed reading from secret file [%s]. Error %i, %s\n", argv[0], secret_file, errno, strerror(errno)); - } - - fprintf(stderr, "The file content is [%s]\n", read_buffer); - - memcpy(enc_key, read_buffer+1, MAXSCALE_SECRETS_ONE); - - memcpy(iv, read_buffer+1+MAXSCALE_SECRETS_ONE, MAXSCALE_SECRETS_INIT_VAL_ONE); - - memcpy(enc_key+ MAXSCALE_SECRETS_ONE, read_buffer+1+MAXSCALE_SECRETS_ONE+MAXSCALE_SECRETS_INIT_VAL_ONE, MAXSCALE_SECRETS_TWO); - memcpy(iv+MAXSCALE_SECRETS_INIT_VAL_ONE, read_buffer+1+MAXSCALE_SECRETS_ONE+MAXSCALE_SECRETS_INIT_VAL_ONE+MAXSCALE_SECRETS_TWO, MAXSCALE_SECRETS_INIT_VAL_TWO); + secrets_readKeys(enc_key, iv, secret_file); fprintf(stderr, "<< Secret 32 is [%s]\n", enc_key); fprintf(stderr, "<< Iv 16 is [%s]\n", iv); - if (close(fd) < 0) { - fprintf(stderr, "%s, failed closing the secret file [%s]. Error %i, %s\n", argv[0], secret_file, errno, strerror(errno)); - } exit(0); } diff --git a/core/secrets.c b/core/secrets.c new file mode 100644 index 000000000..a9a207725 --- /dev/null +++ b/core/secrets.c @@ -0,0 +1,159 @@ +/* + * This file is distributed as part of the SkySQL Gateway. It 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. + * + * 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. + * + * Copyright SkySQL Ab 2013 + */ + + +#include "secrets.h" + +static char secrets_randomchar() { + return (char)((rand() % 78) + 30); +} + +static int secrets_random_str(char *output, int len) { + int i; + srand(time(0L)); + + for ( i = 0; i < len; ++i ) { + output[i] = secrets_randomchar(); + } + + output[len]='\0'; + + return 0; +} + +/** + * secrets_readKeys + * + * This routine reads data from a binary file and exracts the AES encryption key + * and the AES Init Vector + * + * Input parameters must be preallocated + * @param enc_key Will contain the encryption key found in file + * @param iv Will contain the Init vector found in file + * @param secret_file The file with secret keys + * @return 0 on success and 1 on failure + */ + +int secrets_readKeys(char *enc_key, char *iv, char *secret_file) { + struct stat secret_stats; + char read_buffer[1 + AES_BLOCK_SIZE * 2 + AES_BLOCK_SIZE + 3]=""; + int fd =0; + int secret_file_size = 0; + + /* open secret file */ + fd = open(secret_file, O_RDONLY); + + if (fd < 0) { + fprintf(stderr, "secrets_readKeys, failed opening secret file [%s]. Error %i, %s\n", secret_file, errno, strerror(errno)); + return 1; + + } + + /* accessing file details */ + if (fstat(fd, &secret_stats) < 0) { + fprintf(stderr, "secrets_readKeys, failed accessing secret file details [%s]. Error %i, %s\n", secret_file, errno, strerror(errno)); + return 1; + } + + secret_file_size = secret_stats.st_size; + + fprintf(stderr, "The secret file has %i bytes\n", secret_file_size); + + /* read all data from file */ + if (read(fd, read_buffer, sizeof(read_buffer)-1) < 0) { + fprintf(stderr, "secrets_readKeys, failed reading from secret file [%s]. Error %i, %s\n", secret_file, errno, strerror(errno)); + return 1; + } + + /* Now filling input parameters */ + memcpy(enc_key, read_buffer+1, MAXSCALE_SECRETS_ONE); + memcpy(iv, read_buffer+1+MAXSCALE_SECRETS_ONE, MAXSCALE_SECRETS_INIT_VAL_ONE); + memcpy(enc_key+ MAXSCALE_SECRETS_ONE, read_buffer+1+MAXSCALE_SECRETS_ONE+MAXSCALE_SECRETS_INIT_VAL_ONE, MAXSCALE_SECRETS_TWO); + memcpy(iv+MAXSCALE_SECRETS_INIT_VAL_ONE, read_buffer+1+MAXSCALE_SECRETS_ONE+MAXSCALE_SECRETS_INIT_VAL_ONE+MAXSCALE_SECRETS_TWO, MAXSCALE_SECRETS_INIT_VAL_TWO); + + /* Close the file */ + if (close(fd) < 0) { + fprintf(stderr, "secrets_readKeys, failed closing the secret file [%s]. Error %i, %s\n", secret_file, errno, strerror(errno)); + return 1; + } + + return 0; +} + +/** + * secrets_writeKeys + * + * This routine writes into a binary file the AES encryption key + * and the AES Init Vector + * + * @param secret_file The file with secret keys + * @return 0 on success and 1 on failure + */ +int secrets_writeKeys(char *secret_file) +{ + char enc_key[1 + AES_BLOCK_SIZE * 2]=""; + char iv[1 + AES_BLOCK_SIZE]=""; + char secret_buffer[1 + AES_BLOCK_SIZE * 3 + 3] = ""; + char scramble_secret[1 + AES_BLOCK_SIZE * 3 + 3] = ""; + + char one_byte[1 + 1]=""; + char two_bytes[1 + 2]=""; + + int fd =0; + + /* Open for writing | Create | Truncate the file for writing */ + fd = open(secret_file, O_CREAT | O_WRONLY | O_TRUNC); + + if (fd < 0) { + fprintf(stderr, "secrets_createKeys, failed opening secret file [%s]. Error %i, %s\n", secret_file, errno, strerror(errno)); + return 1; + } + + srand(time(NULL)); + secrets_random_str(secret_buffer, AES_BLOCK_SIZE * 3 + 3); + + /* assign key and iv from random buffer */ + memcpy(one_byte, secret_buffer, 1); + memcpy(enc_key, secret_buffer + 1, AES_BLOCK_SIZE * 2); + memcpy(iv, secret_buffer + 1 + AES_BLOCK_SIZE * 2, AES_BLOCK_SIZE); + memcpy(two_bytes, secret_buffer + 1 + AES_BLOCK_SIZE * 2 + AES_BLOCK_SIZE + 1, 2); + + //fprintf(stderr, "<<< Key32 is [%s]\n", enc_key); + //fprintf(stderr, "<<< IV16 is [%s]\n", iv); + + /* prepare data */ + memcpy(scramble_secret, one_byte, 1); + memcpy(scramble_secret + 1, enc_key, MAXSCALE_SECRETS_ONE); + memcpy(scramble_secret + 1 + MAXSCALE_SECRETS_ONE, iv, MAXSCALE_SECRETS_INIT_VAL_ONE); + memcpy(scramble_secret + 1 + MAXSCALE_SECRETS_ONE + MAXSCALE_SECRETS_INIT_VAL_ONE, enc_key + MAXSCALE_SECRETS_ONE, MAXSCALE_SECRETS_TWO); + memcpy(scramble_secret + 1 + MAXSCALE_SECRETS_ONE + MAXSCALE_SECRETS_INIT_VAL_ONE + MAXSCALE_SECRETS_TWO, iv + MAXSCALE_SECRETS_INIT_VAL_ONE, MAXSCALE_SECRETS_INIT_VAL_TWO); + memcpy(scramble_secret + 1 + MAXSCALE_SECRETS_ONE + MAXSCALE_SECRETS_INIT_VAL_ONE + MAXSCALE_SECRETS_TWO + MAXSCALE_SECRETS_INIT_VAL_TWO, two_bytes, 2); + + /* Write data */ + if(write(fd, scramble_secret, sizeof(scramble_secret)-1) < 0) { + fprintf(stderr, "secrets_createKeys, failed writing into secret file [%s]. Error %i, %s\n", secret_file, errno, strerror(errno)); + return 1; + } + + /* close file */ + if (close(fd) < 0) { + fprintf(stderr, "secrets_createKeys, failed closing the secret file [%s]. Error %i, %s\n", secret_file, errno, strerror(errno)); + } + + return 0; +} diff --git a/include/secrets.h b/include/secrets.h new file mode 100644 index 000000000..9b992d2b2 --- /dev/null +++ b/include/secrets.h @@ -0,0 +1,48 @@ +#ifndef _SECRETS_H +#define _SECRETS_H +/* + * This file is distributed as part of the SkySQL Gateway. It 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. + * + * 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. + * + * Copyright SkySQL Ab 2013 + */ + +/** + * @file secrets.h + * + * @verbatim + * Revision History + * + * Date Who Description + * 23/06/2013 Massimiliano Pinto Initial implementation + * + * @endverbatim + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#define MAXSCALE_SECRETS_ONE 4 +#define MAXSCALE_SECRETS_TWO 28 +#define MAXSCALE_SECRETS_INIT_VAL_ONE 11 +#define MAXSCALE_SECRETS_INIT_VAL_TWO 5 + +#endif