diff options
Diffstat (limited to 'src/pki/pki.c')
-rw-r--r-- | src/pki/pki.c | 162 |
1 files changed, 141 insertions, 21 deletions
diff --git a/src/pki/pki.c b/src/pki/pki.c index 0b3e8cf8d..962835159 100644 --- a/src/pki/pki.c +++ b/src/pki/pki.c @@ -26,6 +26,7 @@ #include <library.h> #include <credentials/keys/private_key.h> +#include <credentials/certificates/certificate.h> static int usage(char *error) { @@ -34,18 +35,44 @@ static int usage(char *error) if (error) { out = stderr; - fprintf(out, "%s\n\n", error); + fprintf(out, "Error: %s\n", error); } fprintf(out, "strongSwan %s PKI tool\n", VERSION); fprintf(out, "usage:\n"); - fprintf(out, "pki --help\n"); - fprintf(out, " show this usage information\n"); - fprintf(out, "pki --gen [--type rsa|ecdsa] [--size bits] [--form der|pem|pgp\n"); - fprintf(out, " generate a new private key\n"); + fprintf(out, " pki --help\n"); + fprintf(out, " show this usage information\n"); + fprintf(out, " pki --gen [--type rsa|ecdsa] [--size bits] [--form der|pem|pgp]\n"); + fprintf(out, " generate a new private key\n"); + fprintf(out, " pki --pub [--type rsa|ecdsa|x509] [--form der|pem|pgp]\n"); + fprintf(out, " extract the public key from a private key/certificate\n"); return !!error; } /** + * Convert a form string to a encoding type + */ +static bool get_form(char *form, key_encoding_type_t *type, bool pub) +{ + if (streq(form, "der")) + { + *type = pub ? KEY_PUB_ASN1_DER : KEY_PRIV_ASN1_DER; + } + else if (streq(form, "pem")) + { + *type = pub ? KEY_PUB_PEM : KEY_PRIV_PEM; + } + else if (streq(form, "pgp")) + { + *type = pub ? KEY_PUB_PGP : KEY_PRIV_PGP; + } + else + { + return FALSE; + } + return TRUE; +} + +/** * Generate a private key */ static int gen(int argc, char *argv[]) @@ -59,7 +86,7 @@ static int gen(int argc, char *argv[]) struct option long_opts[] = { { "type", required_argument, NULL, 't' }, { "size", required_argument, NULL, 's' }, - { "form", required_argument, NULL, 'f' }, + { "outform", required_argument, NULL, 'o' }, { 0,0,0,0 } }; while (TRUE) @@ -80,22 +107,10 @@ static int gen(int argc, char *argv[]) return usage("invalid key type"); } continue; - case 'f': - if (streq(optarg, "der")) - { - form = KEY_PRIV_ASN1_DER; - } - else if (streq(optarg, "pem")) - { - form = KEY_PRIV_PEM; - } - else if (streq(optarg, "pgp")) + case 'o': + if (!get_form(optarg, &form, FALSE)) { - form = KEY_PRIV_PGP; - } - else - { - return usage("invalid key format"); + return usage("invalid key output format"); } continue; case 's': @@ -152,6 +167,108 @@ static int gen(int argc, char *argv[]) } /** + * Extract a public key from a private key/certificate + */ +static int pub(int argc, char *argv[]) +{ + key_encoding_type_t form = KEY_PUB_ASN1_DER; + credential_type_t type = CRED_PRIVATE_KEY; + int subtype = KEY_RSA; + certificate_t *cert; + private_key_t *private; + public_key_t *public; + chunk_t encoding; + + struct option long_opts[] = { + { "type", required_argument, NULL, 't' }, + { "form", required_argument, NULL, 'f' }, + { 0,0,0,0 } + }; + while (TRUE) + { + switch (getopt_long(argc, argv, "", long_opts, NULL)) + { + case 't': + if (streq(optarg, "rsa")) + { + type = CRED_PRIVATE_KEY; + subtype = KEY_RSA; + } + else if (streq(optarg, "ecdsa")) + { + type = CRED_PRIVATE_KEY; + subtype = KEY_ECDSA; + } + else if (streq(optarg, "x509")) + { + type = CRED_CERTIFICATE; + subtype = CERT_X509; + } + else + { + return usage("invalid input type"); + } + continue; + case 'f': + if (!get_form(optarg, &form, TRUE)) + { + return usage("invalid output format"); + } + continue; + case EOF: + break; + default: + return usage("invalid --pub option"); + } + break; + } + if (type == CRED_PRIVATE_KEY) + { + private = lib->creds->create(lib->creds, type, subtype, + BUILD_FROM_FD, 0, BUILD_END); + if (!private) + { + fprintf(stderr, "parsing private key failed"); + return 1; + } + public = private->get_public_key(private); + private->destroy(private); + } + else + { + cert = lib->creds->create(lib->creds, type, subtype, + BUILD_FROM_FD, 0, BUILD_END); + if (!cert) + { + fprintf(stderr, "parsing certificate failed"); + return 1; + } + public = cert->get_public_key(cert); + cert->destroy(cert); + } + if (!public) + { + fprintf(stderr, "extracting public key failed\n"); + return 1; + } + if (!public->get_encoding(public, form, &encoding)) + { + fprintf(stderr, "public key encoding failed\n"); + public->destroy(public); + return 1; + } + public->destroy(public); + if (fwrite(encoding.ptr, encoding.len, 1, stdout) != 1) + { + fprintf(stderr, "writing public key failed\n"); + free(encoding.ptr); + return 1; + } + free(encoding.ptr); + return 0; +} + +/** * Library initialization and operation parsing */ int main(int argc, char *argv[]) @@ -159,6 +276,7 @@ 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' }, { 0,0,0,0 } }; @@ -182,6 +300,8 @@ int main(int argc, char *argv[]) return usage(NULL); case 'g': return gen(argc, argv); + case 'p': + return pub(argc, argv); default: return usage("invalid operation"); } |