add --key-gen option to fwknopd (suggested by Jonathan Bennett)

This commit is contained in:
Michael Rash 2015-05-20 08:55:17 -07:00
parent 3e2e73ff99
commit ceb1713976
12 changed files with 209 additions and 34 deletions

View File

@ -1,5 +1,6 @@
Jonathan Bennett Jonathan Bennett
- Contributed OpenWRT support - see the extras/openwrt/ directory. - Contributed OpenWRT support - see the extras/openwrt/ directory.
- Suggested the addition of the --key-gen option to fwknopd.
Sebastien Jeanquier Sebastien Jeanquier
- Assisted with getting fwknop included in BackTrack Linux - the choice - Assisted with getting fwknop included in BackTrack Linux - the choice

View File

@ -1,3 +1,8 @@
fwknop-2.6.7 (05//2015):
- Added --key-gen to fwknopd. This feature was suggested by Jonathan
Bennett, and will help with ease of use efforts. The first platform to
take advantage of this will likely be OpenWRT thanks to Jonathan.
fwknop-2.6.6 (04/23/2015): fwknop-2.6.6 (04/23/2015):
- [server] Add the ability for fwknopd to function as an generic SPA - [server] Add the ability for fwknopd to function as an generic SPA
gateway. This allows scenarios such as the fwknopd system providing DHCP gateway. This allows scenarios such as the fwknopd system providing DHCP

View File

@ -199,7 +199,7 @@ static int critical_var_array[] =
}; };
/** /**
* @brief Generate Rijndael + HMAC keys from /dev/random (base64 encoded) and exit. * @brief Generate Rijndael + HMAC keys from /dev/urandom (base64 encoded).
* *
* @param options FKO command line option structure * @param options FKO command line option structure
*/ */

View File

@ -69,8 +69,6 @@
#define MAX_HOSTNAME_LEN 70 #define MAX_HOSTNAME_LEN 70
#define MAX_URL_HOST_LEN 256 #define MAX_URL_HOST_LEN 256
#define MAX_URL_PATH_LEN 1024 #define MAX_URL_PATH_LEN 1024
#define MAX_KEY_LEN 128
#define MAX_B64_KEY_LEN 180
/* fwknop client configuration parameters and values /* fwknop client configuration parameters and values
*/ */
@ -156,10 +154,10 @@ typedef struct fko_cli_options
unsigned char use_gpg; unsigned char use_gpg;
unsigned char use_gpg_agent; unsigned char use_gpg_agent;
unsigned char gpg_no_signing_pw; unsigned char gpg_no_signing_pw;
unsigned char key_gen;
int time_offset_plus; int time_offset_plus;
int time_offset_minus; int time_offset_minus;
int fw_timeout; int fw_timeout;
int key_gen;
char use_rc_stanza[MAX_LINE_LEN]; char use_rc_stanza[MAX_LINE_LEN];
unsigned char got_named_stanza; unsigned char got_named_stanza;

View File

@ -157,6 +157,9 @@ enum {
#define MAX_GPG_KEY_ID 128 #define MAX_GPG_KEY_ID 128
#define MAX_USERNAME_LEN 30 #define MAX_USERNAME_LEN 30
#define MAX_KEY_LEN 128
#define MAX_B64_KEY_LEN 180
/* Command line argument / argv handling /* Command line argument / argv handling
*/ */
#define MAX_CMDLINE_ARGS 30 /*!< should be way more than enough */ #define MAX_CMDLINE_ARGS 30 /*!< should be way more than enough */

View File

@ -196,6 +196,11 @@ GENERAL OPTIONS
keys are generally more secure than passphrases that are typed in from the keys are generally more secure than passphrases that are typed in from the
command line. command line.
*--key-gen-file*='<file>'::
Write generated keys to the specified file. Note that the file is
overwritten if it already exists. If this option is not given, then
*--key-gen* writes the keys to stdout.
*--key-len*='<length>':: *--key-len*='<length>'::
Specify the number of bytes for a generated Rijndael key. The maximum size Specify the number of bytes for a generated Rijndael key. The maximum size
is currently 128 bytes. is currently 128 bytes.

View File

@ -141,6 +141,10 @@ enum {
FW_LIST = 0x200, FW_LIST = 0x200,
FW_LIST_ALL, FW_LIST_ALL,
FW_FLUSH, FW_FLUSH,
KEY_GEN_FILE,
KEY_LEN,
HMAC_KEY_LEN,
HMAC_DIGEST_TYPE,
AFL_PKT_FILE, AFL_PKT_FILE,
GPG_HOME_DIR, GPG_HOME_DIR,
GPG_EXE_PATH, GPG_EXE_PATH,
@ -178,6 +182,11 @@ static struct option cmd_opts[] =
{"fault-injection-tag", 1, NULL, FAULT_INJECTION_TAG}, {"fault-injection-tag", 1, NULL, FAULT_INJECTION_TAG},
{"help", 0, NULL, 'h'}, {"help", 0, NULL, 'h'},
{"interface", 1, NULL, 'i'}, {"interface", 1, NULL, 'i'},
{"key-gen", 0, NULL, 'k'},
{"key-gen-file", 1, NULL, KEY_GEN_FILE },
{"key-len", 1, NULL, KEY_LEN },
{"hmac-key-len", 1, NULL, HMAC_KEY_LEN },
{"hmac-digest-type", 1, NULL, HMAC_DIGEST_TYPE },
{"kill", 0, NULL, 'K' }, {"kill", 0, NULL, 'K' },
{"fw-flush", 0, NULL, FW_FLUSH }, {"fw-flush", 0, NULL, FW_FLUSH },
{"fw-list", 0, NULL, FW_LIST }, {"fw-list", 0, NULL, FW_LIST },

View File

@ -201,6 +201,60 @@ validate_int_var_ranges(fko_srv_options_t *opts)
return; return;
} }
/**
* @brief Generate Rijndael + HMAC keys from /dev/urandom (base64 encoded).
*
* @param options FKO command line option structure
*/
static void
generate_keys(fko_srv_options_t *options)
{
char key_base64[MAX_B64_KEY_LEN+1];
char hmac_key_base64[MAX_B64_KEY_LEN+1];
FILE *key_gen_file_ptr = NULL;
int res;
/* Zero out the key buffers */
memset(key_base64, 0x00, sizeof(key_base64));
memset(hmac_key_base64, 0x00, sizeof(hmac_key_base64));
/* Generate the key through libfko */
res = fko_key_gen(key_base64, FKO_DEFAULT_KEY_LEN,
hmac_key_base64, FKO_DEFAULT_HMAC_KEY_LEN,
FKO_DEFAULT_HMAC_MODE);
if(res != FKO_SUCCESS)
{
log_msg(LOG_ERR, "%s: fko_key_gen: Error %i - %s",
MY_NAME, res, fko_errstr(res));
clean_exit(options, NO_FW_CLEANUP, EXIT_FAILURE);
}
if(options->key_gen_file[0] != '\0')
{
if ((key_gen_file_ptr = fopen(options->key_gen_file, "w")) == NULL)
{
log_msg(LOG_INFO, "Unable to create key gen file: %s: %s",
options->key_gen_file, strerror(errno));
clean_exit(options, NO_FW_CLEANUP, EXIT_FAILURE);
}
fprintf(key_gen_file_ptr, "KEY_BASE64: %s\nHMAC_KEY_BASE64: %s\n",
key_base64, hmac_key_base64);
fclose(key_gen_file_ptr);
log_msg(LOG_INFO,
"[+] Wrote Rijndael and HMAC keys to: %s",
options->key_gen_file);
}
else
{
log_msg(LOG_INFO,
"KEY_BASE64: %s\nHMAC_KEY_BASE64: %s",
key_base64, hmac_key_base64);
}
clean_exit(options, NO_FW_CLEANUP, EXIT_SUCCESS);
}
/* Parse the config file... /* Parse the config file...
*/ */
static void static void
@ -882,6 +936,20 @@ validate_options(fko_srv_options_t *opts)
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
} }
if(opts->key_gen)
{
/* Set defaults and validate for --key-gen mode
*/
if(opts->key_len == 0)
opts->key_len = FKO_DEFAULT_KEY_LEN;
if(opts->hmac_key_len == 0)
opts->hmac_key_len = FKO_DEFAULT_HMAC_KEY_LEN;
if(opts->hmac_type == 0)
opts->hmac_type = FKO_DEFAULT_HMAC_MODE;
}
return; return;
} }
@ -1130,6 +1198,44 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
case IPT_DISABLE_CHECK_SUPPORT: case IPT_DISABLE_CHECK_SUPPORT:
opts->ipt_disable_check_support = 1; opts->ipt_disable_check_support = 1;
break; break;
case 'k':
opts->key_gen = 1;
break;
case KEY_GEN_FILE:
opts->key_gen = 1;
strlcpy(opts->key_gen_file, optarg, sizeof(opts->key_gen_file));
break;
case KEY_LEN: /* used in --key-gen mode only */
opts->key_len = strtol_wrapper(optarg, 1,
MAX_KEY_LEN, NO_EXIT_UPON_ERR, &is_err);
if(is_err != FKO_SUCCESS)
{
log_msg(LOG_ERR,
"Invalid key length '%s', must be in [%d-%d]",
optarg, 1, MAX_KEY_LEN);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
break;
case HMAC_DIGEST_TYPE: /* used in --key-gen mode only */
if((opts->hmac_type = hmac_digest_strtoint(optarg)) < 0)
{
log_msg(LOG_ERR,
"* Invalid hmac digest type: %s, use {md5,sha1,sha256,sha384,sha512}",
optarg);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
break;
case HMAC_KEY_LEN: /* used in --key-gen mode only */
opts->hmac_key_len = strtol_wrapper(optarg, 1,
MAX_KEY_LEN, NO_EXIT_UPON_ERR, &is_err);
if(is_err != FKO_SUCCESS)
{
log_msg(LOG_ERR,
"Invalid hmac key length '%s', must be in [%d-%d]",
optarg, 1, MAX_KEY_LEN);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
break;
case 'K': case 'K':
opts->kill = 1; opts->kill = 1;
break; break;
@ -1190,6 +1296,9 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
*/ */
validate_options(opts); validate_options(opts);
if(opts->key_gen)
generate_keys(opts);
return; return;
} }

View File

@ -585,10 +585,14 @@ typedef struct fko_srv_options
unsigned char fw_list; /* List current firewall rules */ unsigned char fw_list; /* List current firewall rules */
unsigned char fw_list_all; /* List all current firewall rules */ unsigned char fw_list_all; /* List all current firewall rules */
unsigned char fw_flush; /* Flush current firewall rules */ unsigned char fw_flush; /* Flush current firewall rules */
unsigned char key_gen; /* Generate keys and exit */
unsigned char exit_after_parse_config; /* Parse config and exit */
/* Operational flags
*/
unsigned char test; /* Test mode flag */ unsigned char test; /* Test mode flag */
unsigned char afl_fuzzing; /* SPA pkts from stdin for AFL fuzzing */ unsigned char afl_fuzzing; /* SPA pkts from stdin for AFL fuzzing */
unsigned char verbose; /* Verbose mode flag */ unsigned char verbose; /* Verbose mode flag */
unsigned char exit_after_parse_config; /* Parse config and exit */
unsigned char enable_udp_server; /* Enable UDP server mode */ unsigned char enable_udp_server; /* Enable UDP server mode */
unsigned char firewd_disable_check_support; /* Don't use firewall-cmd ... -C */ unsigned char firewd_disable_check_support; /* Don't use firewall-cmd ... -C */
@ -605,6 +609,13 @@ typedef struct fko_srv_options
int tcp_server_pid; int tcp_server_pid;
int lock_fd; int lock_fd;
/* Values used in --key-gen mode only
*/
char key_gen_file[MAX_PATH_LEN];
int key_len;
int hmac_key_len;
int hmac_type;
#if USE_FILE_CACHE #if USE_FILE_CACHE
struct digest_cache_list *digest_cache; /* In-memory digest cache list */ struct digest_cache_list *digest_cache; /* In-memory digest cache list */
#endif #endif

View File

@ -390,6 +390,14 @@
'exec_err' => $YES, 'exec_err' => $YES,
'cmdline' => "$default_client_args --key-gen -K " . 'A'x1030 'cmdline' => "$default_client_args --key-gen -K " . 'A'x1030
}, },
{
'category' => 'basic operations',
'subcategory' => 'server',
'detail' => '--key-gen file path (-K) too long',
'function' => \&generic_exec,
'exec_err' => $YES,
'cmdline' => "$fwknopdCmd --key-gen --key-gen-file " . 'A'x1030
},
{ {
'category' => 'basic operations', 'category' => 'basic operations',

View File

@ -421,33 +421,6 @@
'key_file' => $cf{'rc_named_key'}, 'key_file' => $cf{'rc_named_key'},
}, },
### --key-gen tests
{
'category' => 'Rijndael',
'subcategory' => 'client',
'detail' => '--key-gen',
'function' => \&generic_exec,
'cmdline' => "$fwknopCmd --key-gen",
'positive_output_matches' => [qr/^KEY_BASE64\:?\s\S{10}/,
qw/HMAC_KEY_BASE64\:?\s\S{10}/],
},
{
'category' => 'Rijndael',
'subcategory' => 'client',
'detail' => "--key-gen $uniq_keys key uniqueness",
'function' => \&key_gen_uniqueness,
'cmdline' => "$fwknopCmd --key-gen", ### no valgrind string (too slow for 100 client exec's)
'disable_valgrind' => $YES,
},
{
'category' => 'Rijndael',
'subcategory' => 'client',
'detail' => '--key-gen to file',
'function' => \&generic_exec,
'cmdline' => "$fwknopCmd --key-gen --key-gen-file $key_gen_file",
'positive_output_matches' => [qr/Wrote.*\skeys/],
},
### rc file tests ### rc file tests
{ {
'category' => 'Rijndael', 'category' => 'Rijndael',

View File

@ -58,6 +58,59 @@
'exec_err' => $YES, 'exec_err' => $YES,
}, },
### --key-gen tests
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'client',
'detail' => '--key-gen',
'function' => \&generic_exec,
'cmdline' => "$fwknopCmd --key-gen",
'positive_output_matches' => [qr/^KEY_BASE64\:?\s\S{10}/,
qw/HMAC_KEY_BASE64\:?\s\S{10}/],
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'server',
'detail' => '--key-gen',
'function' => \&generic_exec,
'cmdline' => "$fwknopdCmd --key-gen",
'positive_output_matches' => [qr/^KEY_BASE64\:?\s\S{10}/,
qw/HMAC_KEY_BASE64\:?\s\S{10}/],
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'client',
'detail' => "--key-gen $uniq_keys key uniqueness",
'function' => \&key_gen_uniqueness,
'cmdline' => "$fwknopCmd --key-gen", ### no valgrind string (too slow for 100 exec's)
'disable_valgrind' => $YES,
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'server',
'detail' => "--key-gen $uniq_keys key uniqueness",
'function' => \&key_gen_uniqueness,
'cmdline' => "$fwknopdCmd --key-gen", ### no valgrind string (too slow for 100 exec's)
'disable_valgrind' => $YES,
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'client',
'detail' => '--key-gen to file',
'function' => \&generic_exec,
'cmdline' => "$fwknopCmd --key-gen --key-gen-file $key_gen_file",
'positive_output_matches' => [qr/Wrote.*\skeys/],
},
{
'category' => 'Rijndael+HMAC',
'subcategory' => 'server',
'detail' => '--key-gen to file',
'function' => \&generic_exec,
'cmdline' => "$fwknopdCmd --key-gen --key-gen-file $key_gen_file",
'positive_output_matches' => [qr/Wrote.*\skeys/],
},
### complete cycle tests
{ {
'category' => 'Rijndael+HMAC', 'category' => 'Rijndael+HMAC',
'subcategory' => 'client+server', 'subcategory' => 'client+server',