--- corosync-2.4.2.orig/exec/totemconfig.c 2017-07-10 10:47:11.640061522 +0800 +++ corosync-2.4.2/exec/totemconfig.c 2017-07-10 12:47:33.936275775 +0800 @@ -1416,7 +1416,6 @@ { int fd; int res; - ssize_t expected_key_len = sizeof (totem_config->private_key); int saved_errno; char error_str[100]; const char *error_ptr; @@ -1430,7 +1429,7 @@ goto parse_error; } - res = read (fd, totem_config->private_key, expected_key_len); + res = read (fd, totem_config->private_key, TOTEM_PRIVATE_KEY_LEN_MAX); saved_errno = errno; close (fd); @@ -1442,15 +1441,14 @@ goto parse_error; } - totem_config->private_key_len = expected_key_len; - - if (res != expected_key_len) { + if (res < TOTEM_PRIVATE_KEY_LEN_MIN) { snprintf (error_string_response, sizeof(error_string_response), - "Could only read %d bits of 1024 bits from %s.\n", - res * 8, key_location); + "Could only read %d bits of minimum %u bits from %s.\n", + res * 8, TOTEM_PRIVATE_KEY_LEN_MIN * 8, key_location); goto parse_error; } + totem_config->private_key_len = res; return 0; parse_error: @@ -1467,8 +1465,8 @@ int res; size_t key_len; - memset (totem_config->private_key, 0, 128); - totem_config->private_key_len = 128; + memset (totem_config->private_key, 0, sizeof(totem_config->private_key)); + totem_config->private_key_len = 0; if (strcmp(totem_config->crypto_cipher_type, "none") == 0 && strcmp(totem_config->crypto_hash_type, "none") == 0) { @@ -1485,15 +1483,19 @@ got_key = 1; } else { /* Or the key itself may be in the cmap */ if (icmap_get("totem.key", NULL, &key_len, NULL) == CS_OK) { - if (key_len > sizeof (totem_config->private_key)) { + if (key_len > sizeof(totem_config->private_key)) { sprintf(error_string_response, "key is too long"); goto key_error; } + if (key_len < TOTEM_PRIVATE_KEY_LEN_MIN) { + sprintf(error_string_response, "key is too short"); + goto key_error; + } if (icmap_get("totem.key", totem_config->private_key, &key_len, NULL) == CS_OK) { totem_config->private_key_len = key_len; got_key = 1; } else { - sprintf(error_string_response, "can't store private key"); + sprintf(error_string_response, "can't store load key"); goto key_error; } } --- corosync-2.4.2.orig/include/corosync/totem/totem.h 2016-11-08 00:39:12.000000000 +0800 +++ corosync-2.4.2/include/corosync/totem/totem.h 2017-07-10 12:38:17.344259264 +0800 @@ -90,7 +90,11 @@ int log_subsys_id; }; -enum { TOTEM_PRIVATE_KEY_LEN = 128 }; +enum { + TOTEM_PRIVATE_KEY_LEN = 128, + TOTEM_PRIVATE_KEY_LEN_MIN = 1024, + TOTEM_PRIVATE_KEY_LEN_MAX = 4096 +}; enum { TOTEM_RRP_MODE_BYTES = 64 }; typedef enum { @@ -119,7 +123,7 @@ /* * key information */ - unsigned char private_key[TOTEM_PRIVATE_KEY_LEN]; + unsigned char private_key[TOTEM_PRIVATE_KEY_LEN_MAX]; unsigned int private_key_len; --- corosync-2.4.2.orig/tools/corosync-keygen.c 2016-11-08 00:39:12.000000000 +0800 +++ corosync-2.4.2/tools/corosync-keygen.c 2017-07-10 11:30:12.340138080 +0800 @@ -1,10 +1,11 @@ /* * Copyright (c) 2004 MontaVista Software, Inc. - * Copyright (c) 2005-2011 Red Hat, Inc. + * Copyright (c) 2005-2017 Red Hat, Inc. * * All rights reserved. * * Author: Steven Dake (sdake@redhat.com) + * Jan Friesse (jfriesse@redhat.com) * * This software licensed under BSD license, the text of which follows: * @@ -47,16 +48,25 @@ #include +#include + #define DEFAULT_KEYFILE COROSYSCONFDIR "/authkey" +#define DEFAULT_KEYFILE_LEN TOTEM_PRIVATE_KEY_LEN_MIN + +#define DEFAULT_RANDOM_DEV "/dev/urandom" + static const char usage[] = - "Usage: corosync-keygen [-k ] [-l]\n" + "Usage: corosync-keygen [-k ] [-s size] [-m ] [-l] [-h]\n" " -k / --key-file= - Write to the specified keyfile\n" " instead of the default " DEFAULT_KEYFILE ".\n" - " -l / --less-secure - Use a less secure random number source\n" - " (/dev/urandom) that is guaranteed not to require user\n" - " input for entropy. This can be used when this\n" - " application is used from a script.\n"; + " -r / --random-file - Random number source file. Default is \n" + " /dev/urandom. As an example /dev/random may be requested\n" + " (that may require user input for entropy).\n" + " -l / --less-secure - Not used, option is kept only\n" + " for compatibility.\n" + " -s / --size - Length of key.\n" + " -h / --help - Print basic usage.\n"; int main (int argc, char *argv[]) @@ -64,27 +74,49 @@ int authkey_fd; int random_fd; char *keyfile = NULL; - unsigned char key[128]; + unsigned char key[TOTEM_PRIVATE_KEY_LEN_MAX]; ssize_t res; ssize_t bytes_read; + size_t key_len = DEFAULT_KEYFILE_LEN; + const char *random_dev = DEFAULT_RANDOM_DEV; + long long int tmpll; + char *ep; int c; int option_index; - int less_secure = 0; static struct option long_options[] = { { "key-file", required_argument, NULL, 'k' }, { "less-secure", no_argument, NULL, 'l' }, + { "random-file", required_argument, NULL, 'r' }, + { "size", required_argument, NULL, 's' }, { "help", no_argument, NULL, 'h' }, { 0, 0, NULL, 0 }, }; - while ((c = getopt_long (argc, argv, "k:lh", + while ((c = getopt_long (argc, argv, "k:r:s:lh", long_options, &option_index)) != -1) { switch (c) { case 'k': keyfile = optarg; break; case 'l': - less_secure = 1; + /* + * Only kept for compatibility + */ + break; + case 'r': + random_dev = optarg; + break; + case 's': + tmpll = strtoll(optarg, &ep, 10); + if (tmpll < TOTEM_PRIVATE_KEY_LEN_MIN || + tmpll > TOTEM_PRIVATE_KEY_LEN_MAX || + errno != 0 || *ep != '\0') { + errx (1, "Unsupported key size (supported <%u,%u>)\n", + TOTEM_PRIVATE_KEY_LEN_MIN, + TOTEM_PRIVATE_KEY_LEN_MAX); + } + + key_len = (size_t)tmpll; break; case 'h': printf ("%s\n", usage); @@ -102,32 +134,30 @@ keyfile = (char *)DEFAULT_KEYFILE; } - if (less_secure) { - printf ("Gathering %lu bits for key from /dev/urandom.\n", (unsigned long)(sizeof (key) * 8)); - random_fd = open ("/dev/urandom", O_RDONLY); - } else { - printf ("Gathering %lu bits for key from /dev/random.\n", (unsigned long)(sizeof (key) * 8)); - printf ("Press keys on your keyboard to generate entropy.\n"); - random_fd = open ("/dev/random", O_RDONLY); - } + printf ("Gathering %lu bits for key from %s.\n", (unsigned long)(key_len * 8), random_dev); + random_fd = open (random_dev, O_RDONLY); if (random_fd == -1) { err (1, "Failed to open random source"); } + if (strcmp(random_dev, "/dev/random") == 0) { + printf ("Press keys on your keyboard to generate entropy.\n"); + } /* * Read random data */ bytes_read = 0; retry_read: - res = read (random_fd, &key[bytes_read], sizeof (key) - bytes_read); + res = read (random_fd, &key[bytes_read], key_len - bytes_read); if (res == -1) { err (1, "Could not read /dev/random"); } bytes_read += res; - if (bytes_read != sizeof (key)) { - printf ("Press keys on your keyboard to generate entropy (bits = %d).\n", (int)(bytes_read * 8)); + if (bytes_read != key_len) { + printf ("Press keys on your keyboard to generate entropy (%d bits still needed).\n", + (int)((key_len - bytes_read) * 8)); goto retry_read; } close (random_fd); @@ -135,7 +165,7 @@ /* * Open key */ - authkey_fd = open (keyfile, O_CREAT|O_WRONLY, 0600); + authkey_fd = open (keyfile, O_CREAT|O_WRONLY|O_TRUNC, 0600); if (authkey_fd == -1) { err (2, "Could not create %s", keyfile); } @@ -148,8 +178,8 @@ /* * Write key */ - res = write (authkey_fd, key, sizeof (key)); - if (res != sizeof (key)) { + res = write (authkey_fd, key, key_len); + if (res != key_len) { err (4, "Could not write %s", keyfile); } --- corosync-2.4.2.orig/man/corosync-keygen.8 2016-11-08 00:39:12.000000000 +0800 +++ corosync-2.4.2/man/corosync-keygen.8 2017-07-10 12:55:30.260289906 +0800 @@ -1,5 +1,5 @@ .\"/* -.\" * Copyright (C) 2010 Red Hat, Inc. +.\" * Copyright (C) 2010-2017 Red Hat, Inc. .\" * .\" * All rights reserved. .\" * @@ -31,11 +31,11 @@ .\" * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF .\" * THE POSSIBILITY OF SUCH DAMAGE. .\" */ -.TH COROSYNC-KEYGEN 8 2010-05-30 +.TH COROSYNC-KEYGEN 8 2017-07-03 .SH NAME corosync-keygen \- Generate an authentication key for Corosync. .SH SYNOPSIS -.B "corosync-keygen [\-k ] [\-l]" +.B "corosync-keygen [\-k ] [-m ] [\-s size] [\-l] [\-h]" .SH DESCRIPTION If you want to configure corosync to use cryptographic techniques to ensure authenticity @@ -57,8 +57,6 @@ If a message "Invalid digest" appears from the corosync executive, the keys are not consistent between processors. .PP -.B Note: corosync-keygen -will ask for user input to assist in generating entropy unless the -l option is used. .SH OPTIONS .TP .B -k @@ -66,30 +64,55 @@ .br The default is /etc/corosync/authkey. .TP +.B -r +Random number source file. Default is /dev/urandom. As an example /dev/random may be +used when really superb randomness is needed. +.TP +.B -s size +Size of the generated key in bytes. Default is 1024 bytes. Allowed range is <1024, 4096>. +.TP +.TP .B -l -Use a less secure random data source that will not require user input to help generate -entropy. This may be useful when this utility is used from a script or hardware random number -generator is not available (f.e. in virtual machine). +Option is not used and it's kept only for compatibility. +.TP +.B -h +Print basic usage. .SH EXAMPLES .TP Generate the key. -.PP +.nf # corosync-keygen -.br Corosync Cluster Engine Authentication key generator. -.br -Gathering 1024 bits for key from /dev/random. -.br -Press keys on your keyboard to generate entropy. -.br -.PP -$ corosync-keygen -l -k /tmp/authkey -.br +Gathering 8192 bits for key from /dev/urandom. +Writing corosync key to /etc/corosync/authkey +.fi + +.TP +Generate longer key and store it in the /tmp/authkey file. +.nf +$ corosync-keygen -s 2048 -k /tmp/authkey Corosync Cluster Engine Authentication key generator. -.br +Gathering 16384 bits for key from /dev/urandom. Writing corosync key to /tmp/authkey. -.br +.fi + +.TP +Generate superb key using /dev/random +.nf +# corosync-keygen -r /dev/random +Corosync Cluster Engine Authentication key generator. +Gathering 8192 bits for key from /dev/random. +Press keys on your keyboard to generate entropy. +Press keys on your keyboard to generate entropy (7928 bits still needed). +Press keys on your keyboard to generate entropy (7880 bits still needed). + ... +Press keys on your keyboard to generate entropy (104 bits still needed). +Press keys on your keyboard to generate entropy (56 bits still needed). +Press keys on your keyboard to generate entropy (8 bits still needed). +Writing corosync key to /etc/corosync/authkey. +.fi + .SH SEE ALSO .BR corosync_overview (8), .BR corosync.conf (5),