/*
* Copyright (C) 2015, Trustees of Indiana University
*
+ * Copyright (c) 2016, Intel Corporation.
+ *
* Author: Jeremy Filizetti <jfilizet@iu.edu>
*/
+#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
/* One week default expiration */
#define SK_DEFAULT_EXPIRE 604800
#define SK_DEFAULT_SK_KEYLEN 256
-#define SK_DEFAULT_DH_KEYLEN 1024
+#define SK_DEFAULT_PRIME_BITS 2048
#define SK_DEFAULT_NODEMAP "default"
/* Names match up with openssl enc and dgst commands */
[SK_CRYPT_AES256_CTR] = "AES-256-CTR",
};
-char *sk_hmac2name[] = {
- [SK_HMAC_EMPTY] = "NONE",
- [SK_HMAC_SHA256] = "SHA256",
- [SK_HMAC_SHA512] = "SHA512",
-};
+const char *sk_hmac2name[] = { "NONE", "SHA256", "SHA512" };
-int sk_name2crypt(char *name)
+static int sk_name2crypt(char *name)
{
int i;
return SK_CRYPT_INVALID;
}
-int sk_name2hmac(char *name)
+enum cfs_crypto_hash_alg sk_name2hmac(char *name)
{
- int i;
+ enum cfs_crypto_hash_alg algo;
+ int i = 0;
- for (i = 0; i < SK_HMAC_MAX; i++) {
- if (strcasecmp(name, sk_hmac2name[i]) == 0)
- return i;
+ /* convert to lower case */
+ while (name[i]) {
+ putchar(tolower(name[i]));
+ i++;
}
- return SK_HMAC_INVALID;
+ if (strcmp(name, "none"))
+ return CFS_HASH_ALG_NULL;
+
+ algo = cfs_crypto_hash_alg(name);
+ if ((algo != CFS_HASH_ALG_SHA256) ||
+ (algo != CFS_HASH_ALG_SHA512))
+ return SK_HMAC_INVALID;
+
+ return algo;
}
-void usage(FILE *fp, char *program)
+static void usage(FILE *fp, char *program)
{
int i;
- fprintf(fp, "Usage %s [OPTIONS] -l <file> | -m <file> | "
- "-r <file> | -w <file>\n", program);
- fprintf(fp, "-l|--load <file> Load key from file into user's "
+ fprintf(fp, "Usage %s [OPTIONS] {-l|-m|-r|-w} <keyfile>\n", program);
+ fprintf(fp, "-l|--load <keyfile> Load key from file into user's "
"session keyring\n");
- fprintf(fp, "-m|--modify <file> Modify a file's key "
- "attributes\n");
- fprintf(fp, "-r|--read <file> Show file's key attributes\n");
- fprintf(fp, "-w|--write <file> Generate key file\n\n");
- fprintf(fp, "Load Options:\n");
- fprintf(fp, "-t|--type <type> Key type (mgs, server, "
- "client)\n\n");
+ fprintf(fp, "-m|--modify <keyfile> Modify keyfile's attributes\n");
+ fprintf(fp, "-r|--read <keyfile> Show keyfile's attributes\n");
+ fprintf(fp, "-w|--write <keyfile> Generate keyfile\n\n");
fprintf(fp, "Modify/Write Options:\n");
- fprintf(fp, "-c|--crypt <num> Cipher for encryption "
+ fprintf(fp, "-c|--crypt <num> Cipher for encryption "
"(Default: AES Counter mode)\n");
- for (i = 0; i < SK_CRYPT_MAX; i++)
+ for (i = 1; i < SK_CRYPT_MAX; i++)
fprintf(fp, " %s\n", sk_crypt2name[i]);
- fprintf(fp, "-h|--hmac <num> Hash alg for HMAC "
+ fprintf(fp, "-i|--hmac <num> Hash algorithm for integrity "
"(Default: SHA256)\n");
- for (i = 0; i < SK_HMAC_MAX; i++)
+ for (i = 1; i < sizeof(sk_hmac2name) / sizeof(sk_hmac2name[0]); i++)
fprintf(fp, " %s\n", sk_hmac2name[i]);
- fprintf(fp, "-e|--expire <num> Seconds before contexts from "
- "key expire (Default: %d seconds)\n", SK_DEFAULT_EXPIRE);
- fprintf(fp, "-f|--fsname <name> File system name for key\n");
- fprintf(fp, "-g|--mgsnids <nids> Comma seperated list of MGS "
- "NIDs. Only required when mgssec is used (Default: "
- "\"\")\n");
- fprintf(fp, "-n|--nodemap <name> Nodemap name for key "
+ fprintf(fp, "-e|--expire <num> Seconds before contexts from "
+ "key expire (Default: %d seconds (%.3g days))\n",
+ SK_DEFAULT_EXPIRE, (double)SK_DEFAULT_EXPIRE / 3600 / 24);
+ fprintf(fp, "-f|--fsname <name> File system name for key\n");
+ fprintf(fp, "-g|--mgsnids <nids> Comma seperated list of MGS "
+ "NIDs. Only required when mgssec is used (Default: \"\")\n");
+ fprintf(fp, "-n|--nodemap <name> Nodemap name for key "
"(Default: \"%s\")\n", SK_DEFAULT_NODEMAP);
- fprintf(fp, "-s|--session <len> DHKE Public key length in bits "
- "(Default: %d)\n", SK_DEFAULT_DH_KEYLEN);
- fprintf(fp, "-k|--shared <len> Shared key length in bits "
+ fprintf(fp, "-p|--prime-bits <len> Prime length (p) for DHKE in "
+ "bits (Default: %d)\n", SK_DEFAULT_PRIME_BITS);
+ fprintf(fp, "-t|--type <type> Key type (mgs, server, "
+ "client)\n");
+ fprintf(fp, "-k|--key-bits <len> Shared key length in bits "
"(Default: %d)\n", SK_DEFAULT_SK_KEYLEN);
- fprintf(fp, "-d|--data <file> Shared key data source "
+ fprintf(fp, "-d|--data <file> Key random data source "
"(Default: /dev/random)\n\n");
fprintf(fp, "Other Options:\n");
- fprintf(fp, "-v|--verbose Increase verbosity for "
- "errors\n");
+ fprintf(fp, "-v|--verbose Increase verbosity for errors\n");
exit(EXIT_FAILURE);
}
-ssize_t get_key_data(char *src, void *buffer, size_t bits)
+static ssize_t get_key_data(char *src, void *buffer, size_t bits)
{
char *ptr = buffer;
size_t remain;
/* convert bits to minimum number of bytes */
remain = (bits + 7) / 8;
+ printf("Reading random data for shared key from '%s'\n", src);
fd = open(src, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "Failed to open %s: %s\n", src,
+ fprintf(stderr, "error: opening '%s': %s\n", src,
strerror(errno));
return -errno;
}
if (rc < 0) {
if (errno == EINTR)
continue;
- fprintf(stderr, "Error reading from %s: %s\n", src,
+ fprintf(stderr, "error: reading from '%s': %s\n", src,
strerror(errno));
rc = -errno;
goto out;
} else if (rc == 0) {
- fprintf(stderr, "Key source too short for key size\n");
+ fprintf(stderr,
+ "error: key source too short for %zd-bit key\n",
+ bits);
rc = -ENODATA;
goto out;
}
return rc;
}
-int write_config_file(char *output_file, struct sk_keyfile_config *config,
- bool overwrite)
+static int write_config_file(char *output_file,
+ struct sk_keyfile_config *config, bool overwrite)
{
size_t rc;
int fd;
fd = open(output_file, flags, 0400);
if (fd < 0) {
- fprintf(stderr, "Failed to open %s: %s\n", output_file,
+ fprintf(stderr, "error: opening '%s': %s\n", output_file,
strerror(errno));
return -errno;
}
rc = write(fd, config, sizeof(*config));
if (rc < 0) {
- fprintf(stderr, "Error writing to %s: %s\n", output_file,
+ fprintf(stderr, "error: writing to '%s': %s\n", output_file,
strerror(errno));
rc = -errno;
-
} else if (rc != sizeof(*config)) {
- fprintf(stderr, "Short write to %s\n", output_file);
+ fprintf(stderr, "error: short write to '%s'\n", output_file);
rc = -ENOSPC;
} else {
return rc;
}
-int print_config(char *filename)
+static int print_config(char *filename)
{
struct sk_keyfile_config *config;
int i;
return EXIT_FAILURE;
if (sk_validate_config(config)) {
- fprintf(stderr, "Key configuration failed validation\n");
+ fprintf(stderr, "error: key configuration failed validation\n");
free(config);
return EXIT_FAILURE;
}
printf("Version: %u\n", config->skc_version);
+ printf("Type: ");
+ if (config->skc_type & SK_TYPE_MGS)
+ printf(" mgs");
+ if (config->skc_type & SK_TYPE_SERVER)
+ printf(" server");
+ if (config->skc_type & SK_TYPE_CLIENT)
+ printf(" client");
+ printf("\n");
printf("HMAC alg: %s\n", sk_hmac2name[config->skc_hmac_alg]);
- printf("Crypt alg: %s\n", sk_crypt2name[config->skc_crypt_alg]);
+ printf("Crypto alg: %s\n", cfs_crypto_hash_name(config->skc_hmac_alg));
printf("Ctx Expiration: %u seconds\n", config->skc_expire);
printf("Shared keylen: %u bits\n", config->skc_shared_keylen);
- printf("Session keylen: %u bits\n", config->skc_session_keylen);
+ printf("Prime length: %u bits\n", config->skc_prime_bits);
printf("File system: %s\n", config->skc_fsname);
- printf("MGS NIDs: ");
+ printf("MGS NIDs: ");
for (i = 0; i < MAX_MGSNIDS; i++) {
if (config->skc_mgsnids[i] == LNET_NID_ANY)
continue;
- printf("%s ", libcfs_nid2str(config->skc_mgsnids[i]));
+ printf(" %s", libcfs_nid2str(config->skc_mgsnids[i]));
}
printf("\n");
printf("Nodemap name: %s\n", config->skc_nodemap);
printf("Shared key:\n");
print_hex(0, config->skc_shared_key, config->skc_shared_keylen / 8);
+ /* Don't print empty keys */
+ for (i = 0; i < SK_MAX_P_BYTES; i++)
+ if (config->skc_p[i] != 0)
+ break;
+
+ if (i != SK_MAX_P_BYTES) {
+ printf("Prime (p):\n");
+ print_hex(0, config->skc_p, config->skc_prime_bits / 8);
+ }
+
free(config);
return EXIT_SUCCESS;
}
-int parse_mgsnids(char *mgsnids, struct sk_keyfile_config *config)
+static int parse_mgsnids(char *mgsnids, struct sk_keyfile_config *config)
{
lnet_nid_t nid;
char *ptr;
nid = libcfs_str2nid(ptr);
if (nid == LNET_NID_ANY) {
- fprintf(stderr, "Invalid MGS NID: %s\n", ptr);
+ fprintf(stderr, "error: invalid MGS NID: %s\n", ptr);
rc = -EINVAL;
break;
}
}
if (i == MAX_MGSNIDS) {
- fprintf(stderr, "Too many MGS NIDs provided\n");
+ fprintf(stderr, "error: more than %u MGS NIDs provided\n", i);
rc = -E2BIG;
}
int main(int argc, char **argv)
{
struct sk_keyfile_config *config;
- char *data = NULL;
+ char *datafile = NULL;
char *input = NULL;
char *load = NULL;
char *modify = NULL;
char *mgsnids = NULL;
char *nodemap = NULL;
char *fsname = NULL;
- int type = SK_TYPE_INVALID;
+ char *tmp;
+ char *tmp2;
int crypt = SK_CRYPT_EMPTY;
- int hmac = SK_HMAC_EMPTY;
+ enum cfs_crypto_hash_alg hmac = CFS_HASH_ALG_NULL;
int expire = -1;
int shared_keylen = -1;
- int session_keylen = -1;
+ int prime_bits = -1;
int verbose = 0;
int i;
int opt;
-
- static struct option long_opt[] = {
- {"crypt", 1, 0, 'c'},
- {"data", 1, 0, 'd'},
- {"expire", 1, 0, 'e'},
- {"fsname", 1, 0, 'f'},
- {"mgsnids", 1, 0, 'g'},
- {"hmac", 1, 0, 'h'},
- {"load", 1, 0, 'l'},
- {"modify", 1, 0, 'm'},
- {"nodemap", 1, 0, 'n'},
- {"read", 1, 0, 'r'},
- {"session", 1, 0, 's'},
- {"shared", 1, 0, 'k'},
- {"type", 1, 0, 't'},
- {"write", 1, 0, 'w'},
- {"verbose", 0, 0, 'v'},
- {"help", 0, 0, 'p'},
- {0, 0, 0, 0},
- };
-
- while ((opt = getopt_long(argc, argv, "c:d:e:f:g:h:l:m:n:pr:s:k:t:w:v",
- long_opt, NULL)) != EOF) {
+ enum sk_key_type type = SK_TYPE_INVALID;
+ bool generate_prime = false;
+ DH *dh;
+
+ static struct option long_opts[] = {
+ { .name = "crypt", .has_arg = required_argument, .val = 'c'},
+ { .name = "data", .has_arg = required_argument, .val = 'd'},
+ { .name = "expire", .has_arg = required_argument, .val = 'e'},
+ { .name = "fsname", .has_arg = required_argument, .val = 'f'},
+ { .name = "mgsnids", .has_arg = required_argument, .val = 'g'},
+ { .name = "help", .has_arg = no_argument, .val = 'h'},
+ { .name = "hmac", .has_arg = required_argument, .val = 'i'},
+ { .name = "integrity", .has_arg = required_argument, .val = 'i'},
+ { .name = "key-bits", .has_arg = required_argument, .val = 'k'},
+ { .name = "shared", .has_arg = required_argument, .val = 'k'},
+ { .name = "load", .has_arg = required_argument, .val = 'l'},
+ { .name = "modify", .has_arg = required_argument, .val = 'm'},
+ { .name = "nodemap", .has_arg = required_argument, .val = 'n'},
+ { .name = "prime-bits", .has_arg = required_argument, .val = 'p'},
+ { .name = "read", .has_arg = required_argument, .val = 'r'},
+ { .name = "type", .has_arg = required_argument, .val = 't'},
+ { .name = "verbose", .has_arg = no_argument, .val = 'v'},
+ { .name = "write", .has_arg = required_argument, .val = 'w'},
+ { .name = NULL, } };
+
+ while ((opt = getopt_long(argc, argv,
+ "c:d:e:f:g:hi:l:m:n:p:r:s:k:t:w:v", long_opts,
+ NULL)) != EOF) {
switch (opt) {
case 'c':
crypt = sk_name2crypt(optarg);
break;
case 'd':
- data = optarg;
+ datafile = optarg;
break;
case 'e':
expire = atoi(optarg);
if (expire < 60)
- fprintf(stderr, "WARNING: Using a short key "
+ fprintf(stderr, "warning: using a %us key "
"expiration may cause issues during "
- "key renegotiation\n");
+ "key renegotiation\n", expire);
break;
case 'f':
fsname = optarg;
if (strlen(fsname) > MTI_NAME_MAXLEN) {
- fprintf(stderr, "File system name too long\n");
+ fprintf(stderr,
+ "error: file system name longer than "
+ "%u characters\n", MTI_NAME_MAXLEN);
return EXIT_FAILURE;
}
break;
mgsnids = optarg;
break;
case 'h':
+ usage(stdout, argv[0]);
+ break;
+ case 'i':
hmac = sk_name2hmac(optarg);
break;
+ case 'k':
+ shared_keylen = atoi(optarg);
+ break;
case 'l':
load = optarg;
break;
+ case 'm':
+ modify = optarg;
+ break;
case 'n':
nodemap = optarg;
if (strlen(nodemap) > LUSTRE_NODEMAP_NAME_LENGTH) {
- fprintf(stderr, "Nodemap name too long\n");
+ fprintf(stderr,
+ "error: nodemap name longer than "
+ "%u characters\n",
+ LUSTRE_NODEMAP_NAME_LENGTH);
return EXIT_FAILURE;
}
break;
- case 'm':
- modify = optarg;
- break;
case 'p':
- usage(stdout, argv[0]);
+ prime_bits = atoi(optarg);
+ if (prime_bits <= 0) {
+ fprintf(stderr,
+ "error: invalid prime length: '%s'\n",
+ optarg);
+ return EXIT_FAILURE;
+ }
break;
case 'r':
input = optarg;
break;
- case 's':
- session_keylen = atoi(optarg);
- break;
- case 'k':
- shared_keylen = atoi(optarg);
- break;
case 't':
- if (!strcasecmp(optarg, "server")) {
- type = SK_TYPE_SERVER;
- } else if (!strcasecmp(optarg, "mgs")) {
- type = SK_TYPE_MGS;
- } else if (!strcasecmp(optarg, "client")) {
- type = SK_TYPE_CLIENT;
- } else {
- fprintf(stderr, "type must be mgs, server, or "
- "client\n");
+ tmp2 = strdup(optarg);
+ if (!tmp2) {
+ fprintf(stderr,
+ "error: failed to allocate type\n");
return EXIT_FAILURE;
}
- break;
- case 'w':
- output = optarg;
+ tmp = strsep(&tmp2, ",");
+ while (tmp != NULL) {
+ if (strcasecmp(tmp, "server") == 0) {
+ type |= SK_TYPE_SERVER;
+ } else if (strcasecmp(tmp, "mgs") == 0) {
+ type |= SK_TYPE_MGS;
+ } else if (strcasecmp(tmp, "client") == 0) {
+ type |= SK_TYPE_CLIENT;
+ } else {
+ fprintf(stderr,
+ "error: invalid type '%s', "
+ "must be mgs, server, or client"
+ "\n", optarg);
+ return EXIT_FAILURE;
+ }
+ tmp = strsep(&tmp2, ",");
+ }
+ free(tmp2);
break;
case 'v':
verbose++;
break;
+ case 'w':
+ output = optarg;
+ break;
default:
- fprintf(stderr, "Unknown option: %c\n", opt);
+ fprintf(stderr, "error: unknown option: '%c'\n", opt);
return EXIT_FAILURE;
break;
}
}
if (optind != argc) {
- fprintf(stderr, "Extraneous arguments provided, check usage\n");
+ fprintf(stderr,
+ "error: extraneous arguments provided, check usage\n");
return EXIT_FAILURE;
}
return print_config(input);
if (load) {
- if (type == SK_TYPE_INVALID) {
- fprintf(stderr, "type must be specified when loading "
- "a key\n");
- return EXIT_FAILURE;
- }
-
- if (sk_load_keyfile(load, type))
+ if (sk_load_keyfile(load))
return EXIT_FAILURE;
return EXIT_SUCCESS;
}
if (crypt == SK_CRYPT_INVALID) {
- fprintf(stderr, "Invalid crypt algorithm specified\n");
+ fprintf(stderr, "error: invalid crypt algorithm specified\n");
return EXIT_FAILURE;
}
if (hmac == SK_HMAC_INVALID) {
- fprintf(stderr, "Invalid HMAC algorithm specified\n");
+ fprintf(stderr, "error: invalid HMAC algorithm specified\n");
return EXIT_FAILURE;
}
if (!config)
return EXIT_FAILURE;
- if (crypt != SK_CRYPT_EMPTY)
- config->skc_crypt_alg = crypt;
- if (hmac != SK_HMAC_EMPTY)
- config->skc_hmac_alg = hmac;
- if (expire != -1)
- config->skc_expire = expire;
- if (shared_keylen != -1)
- config->skc_shared_keylen = shared_keylen;
- if (session_keylen != -1)
- config->skc_session_keylen = session_keylen;
- if (fsname)
- strncpy(config->skc_fsname, fsname, strlen(fsname));
- if (nodemap)
- strncpy(config->skc_nodemap, nodemap, strlen(nodemap));
- if (mgsnids && parse_mgsnids(mgsnids, config))
- goto error;
- if (data && get_key_data(data, config->skc_shared_key,
- config->skc_shared_keylen)) {
- fprintf(stderr, "Failure getting data for key\n");
- goto error;
- }
+ if (type != SK_TYPE_INVALID) {
+ /* generate key when adding client type */
+ if (!(config->skc_type & SK_TYPE_CLIENT) &&
+ type & SK_TYPE_CLIENT)
+ generate_prime = true;
+ else if (!(type & SK_TYPE_CLIENT))
+ memset(config->skc_p, 0, SK_MAX_P_BYTES);
- if (sk_validate_config(config)) {
- fprintf(stderr, "Key configuration failed "
- "validation\n");
- goto error;
+ config->skc_type = type;
+ }
+ if (prime_bits != -1) {
+ memset(config->skc_p, 0, SK_MAX_P_BYTES);
+ if (config->skc_prime_bits != prime_bits &&
+ config->skc_type & SK_TYPE_CLIENT)
+ generate_prime = true;
+ }
+ } else {
+ /* write mode for a new key */
+ if (!fsname && !mgsnids) {
+ fprintf(stderr,
+ "error: missing --fsname or --mgsnids\n");
+ return EXIT_FAILURE;
}
- if (write_config_file(modify, config, true))
- goto error;
+ config = calloc(1, sizeof(*config));
+ if (!config)
+ return EXIT_FAILURE;
- return EXIT_SUCCESS;
- }
+ /* Set the defaults for new key */
+ config->skc_version = SK_CONF_VERSION;
+ config->skc_expire = SK_DEFAULT_EXPIRE;
+ config->skc_shared_keylen = SK_DEFAULT_SK_KEYLEN;
+ config->skc_prime_bits = SK_DEFAULT_PRIME_BITS;
+ config->skc_crypt_alg = SK_CRYPT_AES256_CTR;
+ config->skc_hmac_alg = CFS_HASH_ALG_SHA256;
+ for (i = 0; i < MAX_MGSNIDS; i++)
+ config->skc_mgsnids[i] = LNET_NID_ANY;
- /* write mode for a new key */
- if (!fsname && !mgsnids) {
- fprintf(stderr, "Must provide --fsname, "
- "--mgsnids, or both\n");
- return EXIT_FAILURE;
- }
+ if (type == SK_TYPE_INVALID) {
+ fprintf(stderr, "error: no type specified for key\n");
+ goto error;
+ }
+ config->skc_type = type;
+ generate_prime = type & SK_TYPE_CLIENT;
- config = malloc(sizeof(*config));
- if (!config)
- return EXIT_FAILURE;
+ strncpy(config->skc_nodemap, SK_DEFAULT_NODEMAP,
+ strlen(SK_DEFAULT_NODEMAP));
- /* Set the defaults */
- memset(config, 0, sizeof(*config));
- config->skc_version = SK_CONF_VERSION;
- config->skc_expire = SK_DEFAULT_EXPIRE;
- config->skc_shared_keylen = SK_DEFAULT_SK_KEYLEN;
- config->skc_session_keylen = SK_DEFAULT_DH_KEYLEN;
- config->skc_crypt_alg = SK_CRYPT_AES256_CTR;
- config->skc_hmac_alg = SK_HMAC_SHA256;
- for (i = 0; i < MAX_MGSNIDS; i++)
- config->skc_mgsnids[i] = LNET_NID_ANY;
+ if (!datafile)
+ datafile = "/dev/random";
+ }
if (crypt != SK_CRYPT_EMPTY)
config->skc_crypt_alg = crypt;
- if (hmac != SK_HMAC_EMPTY)
+ if (hmac != CFS_HASH_ALG_NULL)
config->skc_hmac_alg = hmac;
if (expire != -1)
config->skc_expire = expire;
if (shared_keylen != -1)
config->skc_shared_keylen = shared_keylen;
- if (session_keylen != -1)
- config->skc_session_keylen = session_keylen;
+ if (prime_bits != -1)
+ config->skc_prime_bits = prime_bits;
if (fsname)
strncpy(config->skc_fsname, fsname, strlen(fsname));
if (nodemap)
strncpy(config->skc_nodemap, nodemap, strlen(nodemap));
- else
- strncpy(config->skc_nodemap, SK_DEFAULT_NODEMAP,
- strlen(SK_DEFAULT_NODEMAP));
-
if (mgsnids && parse_mgsnids(mgsnids, config))
goto error;
- if (!data)
- data = "/dev/random";
- if (get_key_data(data, config->skc_shared_key,
- config->skc_shared_keylen)) {
- fprintf(stderr, "Failure getting data for key\n");
+ if (sk_validate_config(config)) {
+ fprintf(stderr, "error: key configuration failed validation\n");
goto error;
}
- if (sk_validate_config(config)) {
- fprintf(stderr, "Key configuration failed validation\n");
+ if (datafile && get_key_data(datafile, config->skc_shared_key,
+ config->skc_shared_keylen)) {
+ fprintf(stderr, "error: failure getting key data from '%s'\n",
+ datafile);
goto error;
}
- if (write_config_file(output, config, false))
+ if (generate_prime) {
+ printf("Generating DH parameters, this can take a while...\n");
+ dh = DH_generate_parameters(config->skc_prime_bits,
+ SK_GENERATOR, NULL, NULL);
+ if (BN_num_bytes(dh->p) > SK_MAX_P_BYTES) {
+ fprintf(stderr, "error: cannot generate DH parameters: "
+ "requested length %d exceeds maximum %d\n",
+ config->skc_prime_bits, SK_MAX_P_BYTES * 8);
+ goto error;
+ }
+ if (BN_bn2bin(dh->p, config->skc_p) != BN_num_bytes(dh->p)) {
+ fprintf(stderr,
+ "error: convert BIGNUM p to binary failed\n");
+ goto error;
+ }
+ }
+
+ if (write_config_file(modify ?: output, config, modify))
goto error;
return EXIT_SUCCESS;
error:
- if (config)
- free(config);
+ free(config);
return EXIT_FAILURE;
}