Linux: Support keys in config file (#1093)

- Signing and encryption keys are set through the configuration file.
- SoftEeprom update.
This commit is contained in:
Marcelo Aquino
2018-04-04 20:43:13 +02:00
committed by Mikael Falkvidd
parent 4d90c00f98
commit 3c0b2727a5
6 changed files with 230 additions and 127 deletions
+102 -80
View File
@@ -111,13 +111,7 @@ void print_usage()
" --daemon Run as a daemon.\n" \
" --gen-soft-hmac-key Generate and print a soft hmac key.\n" \
" --gen-soft-serial-key Generate and print a soft serial key.\n" \
" --gen-aes-key Generate and print an aes encryption key.\n" \
" --print-soft-hmac-key Print the soft hmac key from the config file.\n" \
" --print-soft-serial-key Print the soft serial key from the config file.\n" \
" --print-aes-key Print the aes encryption key from the config file.\n" \
" --set-soft-hmac-key Write a soft hmac key to the config file.\n" \
" --set-soft-serial-key Write a soft serial key to the config file.\n" \
" --set-aes-key Write an aes encryption key to the config file.\n");
" --gen-aes-key Generate and print an aes encryption key.\n");
}
void print_soft_sign_hmac_key(uint8_t *key_ptr = NULL)
@@ -129,7 +123,7 @@ void print_soft_sign_hmac_key(uint8_t *key_ptr = NULL)
key_ptr = key;
}
printf("SOFT_HMAC_KEY | ");
printf("soft_hmac_key=");
for (int i = 0; i < 32; i++) {
printf("%02X", key_ptr[i]);
}
@@ -146,20 +140,26 @@ void print_soft_sign_hmac_key(uint8_t *key_ptr = NULL)
printf("\n\n");
}
void generate_soft_sign_hmac_key()
void generate_soft_sign_hmac_key(char *config_file = NULL)
{
uint8_t key[32];
printf("Generating key...");
while (hwGetentropy(&key, sizeof(key)) != sizeof(key));
printf(" done.\n");
printf("To use the new key, update the value in %s witn:\n",
config_file?config_file:MY_LINUX_CONFIG_FILE);
print_soft_sign_hmac_key(key);
printf("To use this key, run mysgw with:\n"
" --set-soft-hmac-key=");
for (int i = 0; i < 32; i++) {
printf("%02X", key[i]);
}
printf("\n");
#if defined(MY_SIGNING_SIMPLE_PASSWD)
printf("Note: The gateway was built with simplified signing using the password: %s\n" \
" Any key set with soft_hmac_key option in the config file is ignored.\n\n",
MY_SIGNING_SIMPLE_PASSWD);
#elif !defined(MY_SIGNING_FEATURE)
printf("Note: The gateway was not built with signing support.\n" \
" Any key set with soft_hmac_key option in the config file is ignored.\n\n");
#endif
}
void set_soft_sign_hmac_key(char *key_str)
@@ -167,7 +167,7 @@ void set_soft_sign_hmac_key(char *key_str)
uint8_t key[32];
if (strlen(key_str) != 64) {
printf("invalid key!\n");
logWarning("Invalid HMAC key!\n");
} else {
for (int i = 0; i < 64; ++i) {
int n;
@@ -187,7 +187,6 @@ void set_soft_sign_hmac_key(char *key_str)
}
}
hwWriteConfigBlock(&key, reinterpret_cast<void*>EEPROM_SIGNING_SOFT_HMAC_KEY_ADDRESS, 32);
print_soft_sign_hmac_key();
}
}
@@ -200,7 +199,7 @@ void print_soft_sign_serial_key(uint8_t *key_ptr = NULL)
key_ptr = key;
}
printf("SOFT_SERIAL | ");
printf("soft_serial_key=");
for (int i = 0; i < 9; i++) {
printf("%02X", key_ptr[i]);
}
@@ -217,20 +216,26 @@ void print_soft_sign_serial_key(uint8_t *key_ptr = NULL)
printf("\n\n");
}
void generate_soft_sign_serial_key()
void generate_soft_sign_serial_key(char *config_file = NULL)
{
uint8_t key[9];
printf("Generating key...");
while (hwGetentropy(&key, sizeof(key)) != sizeof(key));
printf(" done.\n");
printf("To use the new key, update the value in %s witn:\n",
config_file?config_file:MY_LINUX_CONFIG_FILE);
print_soft_sign_serial_key(key);
printf("To use this key, run mysgw with:\n"
" --set-soft-serial-key=");
for (int i = 0; i < 9; i++) {
printf("%02X", key[i]);
}
printf("\n");
#if defined(MY_SIGNING_SIMPLE_PASSWD)
printf("Note: The gateway was built with simplified signing using the password: %s\n" \
" Any key set with soft_serial_key option in the config file is ignored.\n\n",
MY_SIGNING_SIMPLE_PASSWD);
#elif !defined(MY_SIGNING_FEATURE)
printf("Note: The gateway was not built with signing support.\n" \
" Any key set with soft_serial_key option in the config file is ignored.\n\n");
#endif
}
void set_soft_sign_serial_key(char *key_str)
@@ -238,7 +243,7 @@ void set_soft_sign_serial_key(char *key_str)
uint8_t key[9];
if (strlen(key_str) != 18) {
printf("invalid key!\n");
logWarning("Invalid soft serial key!\n");
} else {
for (int i = 0; i < 18; ++i) {
int n;
@@ -258,7 +263,6 @@ void set_soft_sign_serial_key(char *key_str)
}
}
hwWriteConfigBlock(&key, reinterpret_cast<void*>EEPROM_SIGNING_SOFT_SERIAL_ADDRESS, 9);
print_soft_sign_serial_key();
}
}
@@ -267,16 +271,11 @@ void print_aes_key(uint8_t *key_ptr = NULL)
uint8_t key[16];
if (key_ptr == NULL) {
#ifdef MY_ENCRYPTION_SIMPLE_PASSWD
memset(key, 0, 16);
memcpy(key, MY_ENCRYPTION_SIMPLE_PASSWD, strnlen(MY_ENCRYPTION_SIMPLE_PASSWD, 16));
#else
hwReadConfigBlock(&key, reinterpret_cast<void*>EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
#endif
key_ptr = key;
}
printf("AES_KEY | ");
printf("aes_key=");
for (int i = 0; i < 16; i++) {
printf("%02X", key_ptr[i]);
}
@@ -293,20 +292,26 @@ void print_aes_key(uint8_t *key_ptr = NULL)
printf("\n\n");
}
void generate_aes_key()
void generate_aes_key(char *config_file = NULL)
{
uint8_t key[16];
printf("Generating key...");
while (hwGetentropy(&key, sizeof(key)) != sizeof(key));
printf(" done.\n");
printf("To use the new key, update the value in %s witn:\n",
config_file?config_file:MY_LINUX_CONFIG_FILE);
print_aes_key(key);
printf("To use this key, run mysgw with:\n"
" --set-aes-key=");
for (int i = 0; i < 16; i++) {
printf("%02X", key[i]);
}
printf("\n");
#if defined(MY_ENCRYPTION_SIMPLE_PASSWD)
printf("Note: The gateway was built with simplified encryption using the password: %s\n" \
" Any key set with aes_key option in the config file is ignored.\n\n",
MY_ENCRYPTION_SIMPLE_PASSWD);
#elif !defined(MY_ENCRYPTION_FEATURE)
printf("Note: The gateway was not built with encryption support.\n" \
" Any key set with aes_key option in the config file is ignored.\n\n");
#endif
}
void set_aes_key(char *key_str)
@@ -314,7 +319,7 @@ void set_aes_key(char *key_str)
uint8_t key[16];
if (strlen(key_str) != 32) {
printf("invalid key!\n");
logWarning("Invalid AES key!\n");
} else {
for (int i = 0; i < 32; ++i) {
int n;
@@ -334,14 +339,16 @@ void set_aes_key(char *key_str)
}
}
hwWriteConfigBlock(&key, reinterpret_cast<void*>EEPROM_RF_ENCRYPTION_AES_KEY_ADDRESS, 16);
print_aes_key();
}
}
int main(int argc, char *argv[])
{
int opt, daemon = 0, quiet = 0;
char *key = NULL, *config_file = NULL;
char *config_file = NULL;
bool gen_soft_sign_hmac_key = false;
bool gen_soft_sign_serial_key = false;
bool gen_aes_key = false;
/* register the signal handler */
signal(SIGINT, handle_sigint);
@@ -358,17 +365,11 @@ int main(int argc, char *argv[])
{"gen-soft-hmac-key", no_argument, 0, 'A'},
{"gen-soft-serial-key", no_argument, 0, 'B'},
{"gen-aes-key", no_argument, 0, 'C'},
{"print-soft-hmac-key", no_argument, 0, 'D'},
{"print-soft-serial-key", no_argument, 0, 'E'},
{"print-aes-key", no_argument, 0, 'F'},
{"set-soft-hmac-key", required_argument, 0, 'G'},
{"set-soft-serial-key", required_argument, 0, 'H'},
{"set-aes-key", required_argument, 0, 'I'},
{0, 0, 0, 0}
};
int long_index = 0;
while ((opt = getopt_long(argc, argv,"chqABCDEFGHIJ", long_options, &long_index )) != -1) {
while ((opt = getopt_long(argc, argv,"chqABCJ", long_options, &long_index )) != -1) {
switch (opt) {
case 'c':
config_file = strdup(optarg);
@@ -380,35 +381,14 @@ int main(int argc, char *argv[])
quiet = 1;
break;
case 'A':
generate_soft_sign_hmac_key();
exit(EXIT_SUCCESS);
gen_soft_sign_hmac_key = true;
break;
case 'B':
generate_soft_sign_serial_key();
exit(EXIT_SUCCESS);
gen_soft_sign_serial_key = true;
break;
case 'C':
generate_aes_key();
exit(EXIT_SUCCESS);
case 'D':
print_soft_sign_hmac_key();
exit(EXIT_SUCCESS);
case 'E':
print_soft_sign_serial_key();
exit(EXIT_SUCCESS);
case 'F':
print_aes_key();
exit(EXIT_SUCCESS);
case 'G':
key = strdup(optarg);
set_soft_sign_hmac_key(key);
exit(EXIT_SUCCESS);
case 'H':
key = strdup(optarg);
set_soft_sign_serial_key(key);
exit(EXIT_SUCCESS);
case 'I':
key = strdup(optarg);
set_aes_key(key);
exit(EXIT_SUCCESS);
gen_aes_key = true;
break;
case 'J':
daemon = 1;
break;
@@ -418,6 +398,19 @@ int main(int argc, char *argv[])
}
}
if (gen_soft_sign_hmac_key || gen_soft_sign_serial_key || gen_aes_key) {
if (gen_soft_sign_hmac_key) {
generate_soft_sign_hmac_key(config_file);
}
if (gen_soft_sign_serial_key) {
generate_soft_sign_serial_key(config_file);
}
if (gen_aes_key) {
generate_aes_key(config_file);
}
exit(EXIT_SUCCESS);
}
if (daemon) {
if (daemonize() != 0) {
exit(EXIT_FAILURE);
@@ -428,9 +421,6 @@ int main(int argc, char *argv[])
if (config_parse(config_file?config_file:MY_LINUX_CONFIG_FILE) != 0) {
exit(EXIT_FAILURE);
}
if (config_file) {
free(config_file);
}
logSetQuiet(quiet);
logSetLevel(conf.verbose);
@@ -456,6 +446,38 @@ int main(int argc, char *argv[])
_begin(); // Startup MySensors library
// EEPROM is initialized within _begin()
// any operation on it must be done hereafter
#if defined(MY_SIGNING_FEATURE) && !defined(MY_SIGNING_SIMPLE_PASSWD)
// Check if we need to update the signing keys in EEPROM
if (conf.soft_hmac_key) {
set_soft_sign_hmac_key(conf.soft_hmac_key);
} else {
logError("soft_hmac_key was not found in %s\n", config_file?config_file:MY_LINUX_CONFIG_FILE);
exit(EXIT_FAILURE);
}
if (conf.soft_serial_key) {
set_soft_sign_serial_key(conf.soft_serial_key);
} else {
logError("soft_serial_key was not found in %s\n", config_file?config_file:MY_LINUX_CONFIG_FILE);
exit(EXIT_FAILURE);
}
#endif
#if defined(MY_ENCRYPTION_FEATURE) && !defined(MY_ENCRYPTION_SIMPLE_PASSWD)
// Check if we need to update the encryption key in EEPROM
if (conf.aes_key) {
set_aes_key(conf.aes_key);
} else {
logError("aes_key was not found in %s\n", config_file?config_file:MY_LINUX_CONFIG_FILE);
exit(EXIT_FAILURE);
}
#endif
if (config_file) {
free(config_file);
}
for (;;) {
_process(); // Process incoming data
if (loop) {