#include <credentials/certificates/certificate.h>
#include <credentials/certificates/x509.h>
-static void print_gen(FILE *out)
-{
- fprintf(out, " pki --gen [--type rsa|ecdsa] [--size bits] [--outform der|pem|pgp]\n");
- fprintf(out, " generate a new private key\n");
- fprintf(out, " --type type of key, default: rsa\n");
- fprintf(out, " --size keylength in bits, default: rsa 2048, ecdsa 384\n");
- fprintf(out, " --outform encoding of generated private key\n");
-}
-
-static void print_pub(FILE *out)
-{
- fprintf(out, " pki --pub [--in file] [--type rsa|ecdsa|x509] [--outform der|pem|pgp]\n");
- fprintf(out, " extract the public key from a private key/certificate\n");
- fprintf(out, " --in input file, default: stdin\n");
- fprintf(out, " --type type of credential, default: rsa\n");
- fprintf(out, " --outform encoding of extracted public key\n");
-}
+static int help(int argc, char *argv[]);
+static int gen(int argc, char *argv[]);
+static int pub(int argc, char *argv[]);
+static int keyid(int argc, char *argv[]);
+static int self(int argc, char *argv[]);
+static int issue(int argc, char *argv[]);
+static int verify(int argc, char *argv[]);
-static void print_keyid(FILE *out)
-{
- fprintf(out, " pki --keyid [--in file] [--type rsa-priv|ecdsa-priv|pub|x509]\n");
- fprintf(out, " calculate key identifiers of a key/certificate\n");
- fprintf(out, " --in input file, default: stdin\n");
- fprintf(out, " --type type of key, default: rsa-priv\n");
-}
+typedef enum {
+ CMD_HELP = 0,
+ CMD_GEN,
+ CMD_PUB,
+ CMD_KEYID,
+ CMD_SELF,
+ CMD_ISSUE,
+ CMD_VERIFY,
+ CMD_MAX
+} cmd_t;
-static void print_self(FILE *out)
-{
- fprintf(out, " pki --self [--in file] [--type rsa|ecdsa]\n");
- fprintf(out, " --dn distinguished-name [--san subjectAltName]+\n");
- fprintf(out, " [--lifetime days] [--serial hex] [--ca]\n");
- fprintf(out, " [--digest md5|sha1|sha224|sha256|sha384|sha512]\n");
- fprintf(out, " [--options file]\n");
- fprintf(out, " create a self signed certificate\n");
- fprintf(out, " --in private key input file, default: stdin\n");
- fprintf(out, " --type type of input key, default: rsa\n");
- fprintf(out, " --dn subject and issuer distinguished name\n");
- fprintf(out, " --san subjectAltName to include in certificate\n");
- fprintf(out, " --lifetime days the certificate is valid, default: 1080\n");
- fprintf(out, " --serial serial number in hex, default: random\n");
- fprintf(out, " --ca include CA basicConstraint, default: no\n");
- fprintf(out, " --digest digest for signature creation, default: sha1\n");
- fprintf(out, " --options read command line options from file\n");
-}
+#define MAX_OPTIONS 14
-static void print_issue(FILE *out)
-{
- fprintf(out, " pki --issue [--in file] [--type pub|pkcs10]\n");
- fprintf(out, " --cacert file --cakey file\n");
- fprintf(out, " --dn subject-dn [--san subjectAltName]+\n");
- fprintf(out, " [--lifetime days] [--serial hex] [--ca]\n");
- fprintf(out, " [--digest md5|sha1|sha224|sha256|sha384|sha512]\n");
- fprintf(out, " [--options file]\n");
- fprintf(out, " issue a certificate using a CA certificate and key\n");
- fprintf(out, " --in public key/request file to issue, default: stdin\n");
- fprintf(out, " --type type of input, default: pub\n");
- fprintf(out, " --cacert CA certificate file\n");
- fprintf(out, " --cakey CA private key file\n");
- fprintf(out, " --dn distinguished name to include as subject\n");
- fprintf(out, " --san subjectAltName to include in certificate\n");
- fprintf(out, " --lifetime days the certificate is valid, default: 1080\n");
- fprintf(out, " --serial serial number in hex, default: random\n");
- fprintf(out, " --ca include CA basicConstraint, default: no\n");
- fprintf(out, " --digest digest for signature creation, default: sha1\n");
- fprintf(out, " --options read command line options from file\n");
-}
-
-static void print_verify(FILE *out)
-{
- fprintf(out, " pki --verify [--in file] [--ca file]\n");
- fprintf(out, " verify a certificate using the CA certificate\n");
- fprintf(out, " --in x509 certifcate to verify, default: stdin\n");
- fprintf(out, " --cacert CA certificate, default: verify self signed\n");
-}
-
-static void print_version(FILE *out, char *name)
-{
- fprintf(out, "strongSwan %s PKI tool\n", VERSION);
- fprintf(out, "usage:\n");
- fprintf(out, " pki%s --help\n", name);
- fprintf(out, " show this usage information\n");
-}
-
-static int usage(char *error)
-{
- FILE *out = stdout;
-
- if (error)
- {
- out = stderr;
- fprintf(out, "Error: %s\n", error);
- }
- print_version(out, "");
- print_gen(out);
- print_pub(out);
- print_keyid(out);
- print_self(out);
- print_issue(out);
- print_verify(out);
- return error != NULL;
-}
-
-static int usage_gen(char *error)
-{
- FILE *out = stdout;
+static struct {
+ int (*call)(int, char*[]);
+ char op;
+ char *cmd;
+ char *description;
+ char *line[8];
+ struct {
+ char *name;
+ char op;
+ int arg;
+ char *desc;
+ } options[MAX_OPTIONS];
+} cmds[] = {
+ [CMD_HELP] = { help, 'h', "help",
+ "show usage information"
+ },
+ [CMD_GEN] = { gen, 'g', "gen", "generate a new private key",
+ {"[--type rsa|ecdsa] [--size bits] [--outform der|pem|pgp]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"type", 't', 1, "type of key, default: rsa"},
+ {"size", 's', 1, "keylength in bits, default: rsa 2048, ecdsa 384"},
+ {"outform", 'f', 1, "encoding of generated private key"},
+ }
+ },
+ [CMD_PUB] = { pub, 'p', "pub",
+ "extract the public key from a private key/certificate",
+ {"[--in file] [--type rsa|ecdsa|x509] [--outform der|pem|pgp]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"in", 'i', 1, "input file, default: stdin"},
+ {"type", 't', 1, "type of credential, default: rsa"},
+ {"outform", 'f', 1, "encoding of extracted public key"},
+ }
+ },
+ [CMD_KEYID] = { keyid, 'k', "keyid",
+ "calculate key identifiers of a key/certificate",
+ {"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"in", 'i', 1, "input file, default: stdin"},
+ {"type", 't', 1, "type of key, default: rsa-priv"},
+ }
+ },
+ [CMD_SELF] = { self, 's', "self",
+ "create a self signed certificate",
+ {"[--in file] [--type rsa|ecdsa]",
+ " --dn distinguished-name [--san subjectAltName]+",
+ "[--lifetime days] [--serial hex] [--ca]",
+ "[--digest md5|sha1|sha224|sha256|sha384|sha512]",
+ "[--options file]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"in", 'i', 1, "private key input file, default: stdin"},
+ {"type", 't', 1, "type of input key, default: rsa"},
+ {"dn", 'd', 1, "subject and issuer distinguished name"},
+ {"san", 'a', 1, "subjectAltName to include in certificate"},
+ {"lifetime",'l', 1, "days the certificate is valid, default: 1080"},
+ {"serial", 's', 1, "serial number in hex, default: random"},
+ {"ca", 'b', 0, "include CA basicConstraint, default: no"},
+ {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"options", '+', 1, "read command line options from file"},
+ }
+ },
+ [CMD_ISSUE] = { issue, 'i', "issue",
+ "issue a certificate using a CA certificate and key",
+ {"[--in file] [--type pub|pkcs10]",
+ " --cacert file --cakey file",
+ " --dn subject-dn [--san subjectAltName]+",
+ "[--lifetime days] [--serial hex] [--ca]",
+ "[--digest md5|sha1|sha224|sha256|sha384|sha512]",
+ "[--options file]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"in", 'i', 1, "public key/request file to issue, default: stdin"},
+ {"type", 't', 1, "type of input, default: pub"},
+ {"cacert", 'c', 1, "CA certificate file"},
+ {"cakey", 'k', 1, "CA private key file"},
+ {"dn", 'd', 1, "distinguished name to include as subject"},
+ {"san", 'a', 1, "subjectAltName to include in certificate"},
+ {"lifetime",'l', 1, "days the certificate is valid, default: 1080"},
+ {"serial", 's', 1, "serial number in hex, default: random"},
+ {"ca", 'b', 0, "include CA basicConstraint, default: no"},
+ {"digest", 'g', 1, "digest for signature creation, default: sha1"},
+ {"options", '+', 1, "read command line options from file"},
+ }
+ },
+ [CMD_VERIFY] = { verify, 'v', "verify",
+ "verify a certificate using the CA certificate",
+ {"[--in file] [--ca file]"},
+ {
+ {"help", 'h', 0, "show usage information"},
+ {"in", 'i', 1, "x509 certifcate to verify, default: stdin"},
+ {"cacert", 'c', 1, "CA certificate, default: verify self signed"},
+ }
+ },
+};
- if (error)
- {
- out = stderr;
- fprintf(out, "Error: %s\n", error);
- }
- print_version(out, " --gen");
- print_gen(out);
- return error != NULL;
-}
+/**
+ * Global options used by all subcommands
+ */
+static struct option long_opts[countof(cmds) > MAX_OPTIONS ?: MAX_OPTIONS];
-static int usage_pub(char *error)
+/**
+ * Build long_opts for a specific command
+ */
+static void build_opts(cmd_t cmd)
{
- FILE *out = stdout;
+ int i;
- if (error)
+ memset(long_opts, 0, sizeof(long_opts));
+ if (cmd == CMD_HELP)
{
- out = stderr;
- fprintf(out, "Error: %s\n", error);
+ for (i = 0; i < CMD_MAX; i++)
+ {
+ long_opts[i].name = cmds[i].cmd;
+ long_opts[i].val = cmds[i].op;
+ }
}
- print_version(out, " --pub");
- print_pub(out);
- return error != NULL;
-}
-
-static int usage_keyid(char *error)
-{
- FILE *out = stdout;
-
- if (error)
+ else
{
- out = stderr;
- fprintf(out, "Error: %s\n", error);
+ for (i = 0; cmds[cmd].options[i].name; i++)
+ {
+ long_opts[i].name = cmds[cmd].options[i].name;
+ long_opts[i].has_arg = cmds[cmd].options[i].arg;
+ long_opts[i].val = cmds[cmd].options[i].op;
+ }
}
- print_version(out, " --keyid");
- print_keyid(out);
- return error != NULL;
}
-static int usage_self(char *error)
+/**
+ * Print usage text, with an optional error
+ */
+static int usage(cmd_t cmd, char *error)
{
FILE *out = stdout;
+ int i;
if (error)
{
out = stderr;
fprintf(out, "Error: %s\n", error);
}
- print_version(out, " --self");
- print_self(out);
- return error != NULL;
-}
-
-static int usage_issue(char *error)
-{
- FILE *out = stdout;
-
- if (error)
+ fprintf(out, "strongSwan %s PKI tool\n", VERSION);
+ fprintf(out, "usage:\n");
+ if (cmd == CMD_HELP)
{
- out = stderr;
- fprintf(out, "Error: %s\n", error);
+ for (i = 0; i < CMD_MAX; i++)
+ {
+ fprintf(out, " pki --%-6s %s\n", cmds[i].cmd, cmds[i].description);
+ }
}
- print_version(out, " --issue");
- print_issue(out);
- return error != NULL;
-}
-
-static int usage_verify(char *error)
-{
- FILE *out = stdout;
-
- if (error)
+ else
{
- out = stderr;
- fprintf(out, "Error: %s\n", error);
+ for (i = 0; cmds[cmd].line[i]; i++)
+ {
+ if (i == 0)
+ {
+ fprintf(out, " pki --%s %s\n", cmds[cmd].cmd, cmds[cmd].line[i]);
+ }
+ else
+ {
+ fprintf(out, " %s\n", cmds[cmd].line[i]);
+ }
+ }
+ for (i = 0; cmds[cmd].options[i].name; i++)
+ {
+ fprintf(out, " --%-8s %s\n",
+ cmds[cmd].options[i].name, cmds[cmd].options[i].desc);
+ }
}
- print_version(out, " --verify");
- print_verify(out);
return error != NULL;
}
}
/**
+ * Show usage information
+ */
+static int help(int argc, char *argv[])
+{
+ return usage(CMD_HELP, NULL);
+}
+
+/**
* Generate a private key
*/
static int gen(int argc, char *argv[])
private_key_t *key;
chunk_t encoding;
- struct option long_opts[] = {
- { "help", no_argument, NULL, 'h' },
- { "type", required_argument, NULL, 't' },
- { "size", required_argument, NULL, 's' },
- { "outform", required_argument, NULL, 'o' },
- { 0,0,0,0 }
- };
while (TRUE)
{
switch (getopt_long(argc, argv, "", long_opts, NULL))
{
case 'h':
- return usage_gen(NULL);
+ return usage(CMD_GEN, NULL);
case 't':
if (streq(optarg, "rsa"))
{
}
else
{
- return usage_gen("invalid key type");
+ return usage(CMD_GEN, "invalid key type");
}
continue;
case 'o':
if (!get_form(optarg, &form, FALSE))
{
- return usage_gen("invalid key output format");
+ return usage(CMD_GEN, "invalid key output format");
}
continue;
case 's':
size = atoi(optarg);
if (!size)
{
- return usage_gen("invalid key size");
+ return usage(CMD_GEN, "invalid key size");
}
continue;
case EOF:
break;
default:
- return usage_gen("invalid --gen option");
+ return usage(CMD_GEN, "invalid --gen option");
}
break;
}
char *file = NULL;
void *cred;
- struct option long_opts[] = {
- { "help", no_argument, NULL, 'h' },
- { "type", required_argument, NULL, 't' },
- { "outform", required_argument, NULL, 'f' },
- { "in", required_argument, NULL, 'i' },
- { 0,0,0,0 }
- };
while (TRUE)
{
switch (getopt_long(argc, argv, "", long_opts, NULL))
{
case 'h':
- return usage_pub(NULL);
+ return usage(CMD_PUB, NULL);
case 't':
if (streq(optarg, "rsa"))
{
}
else
{
- return usage_pub("invalid input type");
+ return usage(CMD_PUB, "invalid input type");
}
continue;
case 'f':
if (!get_form(optarg, &form, TRUE))
{
- return usage_pub("invalid output format");
+ return usage(CMD_PUB, "invalid output format");
}
continue;
case 'i':
case EOF:
break;
default:
- return usage_pub("invalid --pub option");
+ return usage(CMD_PUB, "invalid --pub option");
}
break;
}
void *cred;
chunk_t id;
- struct option long_opts[] = {
- { "help", no_argument, NULL, 'h' },
- { "type", required_argument, NULL, 't' },
- { "in", required_argument, NULL, 'i' },
- { 0,0,0,0 }
- };
while (TRUE)
{
switch (getopt_long(argc, argv, "", long_opts, NULL))
{
case 'h':
- return usage_keyid(NULL);
+ return usage(CMD_KEYID, NULL);
case 't':
if (streq(optarg, "rsa-priv"))
{
}
else
{
- return usage_keyid("invalid input type");
+ return usage(CMD_KEYID, "invalid input type");
}
continue;
case 'i':
case EOF:
break;
default:
- return usage_keyid("invalid --keyid option");
+ return usage(CMD_KEYID, "invalid --keyid option");
}
break;
}
x509_flag_t flags = 0;
options_t *options;
- struct option long_opts[] = {
- { "help", no_argument, NULL, 'h' },
- { "options", required_argument, NULL, '+' },
- { "type", required_argument, NULL, 't' },
- { "in", required_argument, NULL, 'i' },
- { "dn", required_argument, NULL, 'd' },
- { "san", required_argument, NULL, 'a' },
- { "lifetime", required_argument, NULL, 'l' },
- { "serial", required_argument, NULL, 's' },
- { "digest", required_argument, NULL, 'g' },
- { "ca", no_argument, NULL, 'c' },
- { 0,0,0,0 }
- };
-
options = options_create();
san = linked_list_create();
usage:
san->destroy_offset(san, offsetof(identification_t, destroy));
options->destroy(options);
- return usage_self(error);
+ return usage(CMD_SELF, error);
}
/**
x509_t *x509;
options_t *options;
- struct option long_opts[] = {
- { "help", no_argument, NULL, 'h' },
- { "options", required_argument, NULL, '+' },
- { "type", required_argument, NULL, 't' },
- { "in", required_argument, NULL, 'i' },
- { "cacert", required_argument, NULL, 'c' },
- { "cakey", required_argument, NULL, 'k' },
- { "dn", required_argument, NULL, 'd' },
- { "san", required_argument, NULL, 'a' },
- { "lifetime", required_argument, NULL, 'l' },
- { "serial", required_argument, NULL, 's' },
- { "digest", required_argument, NULL, 'g' },
- { "ca", no_argument, NULL, 'b' },
- { 0,0,0,0 }
- };
-
options = options_create();
san = linked_list_create();
usage:
san->destroy_offset(san, offsetof(identification_t, destroy));
options->destroy(options);
- return usage_issue(error);
+ return usage(CMD_ISSUE, error);
}
/**
switch (getopt_long(argc, argv, "", long_opts, NULL))
{
case 'h':
- return usage_verify(NULL);
+ return usage(CMD_VERIFY, NULL);
case 'i':
file = optarg;
continue;
case EOF:
break;
default:
- return usage_verify("invalid --verify option");
+ return usage(CMD_VERIFY, "invalid --verify option");
}
break;
}
*/
int main(int argc, char *argv[])
{
- struct option long_opts[] = {
- { "help", no_argument, NULL, 'h' },
- { "gen", no_argument, NULL, 'g' },
- { "pub", no_argument, NULL, 'p' },
- { "keyid", no_argument, NULL, 'k' },
- { "self", no_argument, NULL, 's' },
- { "issue", no_argument, NULL, 'i' },
- { "verify", no_argument, NULL, 'v' },
- { 0,0,0,0 }
- };
+ int op, i;
atexit(library_deinit);
if (!library_init(STRONGSWAN_CONF))
exit(SS_RC_INITIALIZATION_FAILED);
}
- switch (getopt_long(argc, argv, "", long_opts, NULL))
- {
- case 'h':
- return usage(NULL);
- case 'g':
- return gen(argc, argv);
- case 'p':
- return pub(argc, argv);
- case 'k':
- return keyid(argc, argv);
- case 's':
- return self(argc, argv);
- case 'i':
- return issue(argc, argv);
- case 'v':
- return verify(argc, argv);
- default:
- return usage("invalid operation");
+ build_opts(CMD_HELP);
+ op = getopt_long(argc, argv, "", long_opts, NULL);
+ for (i = 0; i < CMD_MAX; i++)
+ {
+ if (cmds[i].op == op)
+ {
+ build_opts(i);
+ return cmds[i].call(argc, argv);
+ }
}
+ return usage(CMD_HELP, "invalid operation");
}