client: add keygen command

Add a new command that will generate a random key from /dev/urandom with
given ID, hash function and length.
This commit is contained in:
Miroslav Lichvar 2016-01-14 14:20:54 +01:00
parent 32ac6ffa26
commit 7fcf69ce5f
2 changed files with 66 additions and 0 deletions

View file

@ -3373,6 +3373,7 @@ interface.
* dump command:: Dump measurement histories to files * dump command:: Dump measurement histories to files
* exit command:: Exit from chronyc * exit command:: Exit from chronyc
* help command:: Generate help summary * help command:: Generate help summary
* keygen command:: Generate key for key file
* local command:: Let computer be a server when it is unsynchronised * local command:: Let computer be a server when it is unsynchronised
* makestep command:: Correct the system clock by stepping instead of slewing * makestep command:: Correct the system clock by stepping instead of slewing
* manual command:: Enable/disable/configure options for settime * manual command:: Enable/disable/configure options for settime
@ -3807,6 +3808,31 @@ The exit command exits from chronyc and returns the user to the shell
@subsubsection help @subsubsection help
The help command displays a summary of the commands and their arguments. The help command displays a summary of the commands and their arguments.
@c }}} @c }}}
@c {{{ keygen
@node keygen command
@subsubsection keygen
The @code{keygen} command generates a key that can be added to the
key file (@pxref{keyfile directive}) to allow NTP authentication between
server and client, or peers. The key is generated from the @code{/dev/urandom}
device and it's printed to standard output.
The first argument of the command is the key number, which will be specified
with the @code{key} option of the @code{server} or @code{peer} directives in
the configuration file. The second and third arguments are optional. They
specify the hash function (by default SHA1 or MD5 if SHA1 is not available) and
the number of bits the key should have between 80 and 4096 bits (by default 160
bits).
An example is
@example
keygen 73 SHA1 256
@end example
which generates a 256-bit SHA-1 key with number 73. The printed line would
then be securely transferred and added to key files on both server and client,
or peers.
@c }}}
@c {{{ local @c {{{ local
@node local command @node local command
@subsubsection local @subsubsection local

View file

@ -1255,6 +1255,7 @@ give_help(void)
"dns -4|-6|-46\0Resolve hostnames only to IPv4/IPv6/both addresses\0" "dns -4|-6|-46\0Resolve hostnames only to IPv4/IPv6/both addresses\0"
"timeout <milliseconds>\0Set initial response timeout\0" "timeout <milliseconds>\0Set initial response timeout\0"
"retries <retries>\0Set maximum number of retries\0" "retries <retries>\0Set maximum number of retries\0"
"keygen <id> [<type> [<bits>]]\0Generate key for key file\0"
"exit|quit\0Leave the program\0" "exit|quit\0Leave the program\0"
"help\0Generate this help\0" "help\0Generate this help\0"
"\0"; "\0";
@ -2413,6 +2414,42 @@ process_cmd_retries(const char *line)
/* ================================================== */ /* ================================================== */
static int
process_cmd_keygen(char *line)
{
char hash_name[17];
unsigned char key[512];
unsigned int i, length, id, bits = 160;
#ifdef FEAT_SECHASH
snprintf(hash_name, sizeof (hash_name), "SHA1");
#else
snprintf(hash_name, sizeof (hash_name), "MD5");
#endif
if (sscanf(line, "%u %16s %d", &id, hash_name, &bits) < 1) {
LOG(LOGS_ERR, LOGF_Client, "Invalid syntax for keygen command");
return 0;
}
length = CLAMP(10, (bits + 7) / 8, sizeof (key));
if (HSH_GetHashId(hash_name) < 0) {
LOG(LOGS_ERR, LOGF_Client, "Unknown hash function %s", hash_name);
return 0;
}
UTI_GetRandomBytesUrandom(key, length);
printf("%u %s HEX:", id, hash_name);
for (i = 0; i < length; i++)
printf("%02hhX", key[i]);
printf("\n");
return 1;
}
/* ================================================== */
static int static int
process_line(char *line) process_line(char *line)
{ {
@ -2499,6 +2536,9 @@ process_line(char *line)
do_normal_submit = 0; do_normal_submit = 0;
give_help(); give_help();
ret = 1; ret = 1;
} else if (!strcmp(command, "keygen")) {
ret = process_cmd_keygen(line);
do_normal_submit = 0;
} else if (!strcmp(command, "local")) { } else if (!strcmp(command, "local")) {
do_normal_submit = process_cmd_local(&tx_message, line); do_normal_submit = process_cmd_local(&tx_message, line);
} else if (!strcmp(command, "makestep")) { } else if (!strcmp(command, "makestep")) {