From: Tobias Brunner Date: Tue, 9 Dec 2014 11:54:03 +0000 (+0100) Subject: pki: Add command to export certificates and keys from PKCS#12 containers X-Git-Tag: 5.2.2rc1~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3a26566fa90ad978a2b0e58e84b2200e2293e193;p=thirdparty%2Fstrongswan.git pki: Add command to export certificates and keys from PKCS#12 containers --- diff --git a/src/pki/commands/pkcs12.c b/src/pki/commands/pkcs12.c index a6b260caa4..fe92fa810c 100644 --- a/src/pki/commands/pkcs12.c +++ b/src/pki/commands/pkcs12.c @@ -58,17 +58,88 @@ static int show(pkcs12_t *pkcs12) return 0; } +static int export(pkcs12_t *pkcs12, int index, char *outform) +{ + cred_encoding_type_t form; + enumerator_t *enumerator; + certificate_t *cert; + private_key_t *key; + chunk_t encoding; + int i = 1; + + enumerator = pkcs12->create_cert_enumerator(pkcs12); + while (enumerator->enumerate(enumerator, &cert)) + { + if (i++ == index) + { + form = CERT_ASN1_DER; + if (outform && !get_form(outform, &form, CRED_CERTIFICATE)) + { + return command_usage("invalid output format"); + } + if (cert->get_encoding(cert, form, &encoding)) + { + set_file_mode(stdout, form); + if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1) + { + free(encoding.ptr); + enumerator->destroy(enumerator); + return 0; + } + free(encoding.ptr); + } + fprintf(stderr, "certificate export failed\n"); + enumerator->destroy(enumerator); + return 1; + } + } + enumerator->destroy(enumerator); + + enumerator = pkcs12->create_key_enumerator(pkcs12); + while (enumerator->enumerate(enumerator, &key)) + { + if (i++ == index) + { + form = PRIVKEY_ASN1_DER; + if (outform && !get_form(outform, &form, CRED_PRIVATE_KEY)) + { + return command_usage("invalid output format"); + } + if (key->get_encoding(key, form, &encoding)) + { + set_file_mode(stdout, form); + if (fwrite(encoding.ptr, encoding.len, 1, stdout) == 1) + { + free(encoding.ptr); + enumerator->destroy(enumerator); + return 0; + } + free(encoding.ptr); + } + fprintf(stderr, "private key export failed\n"); + enumerator->destroy(enumerator); + return 0; + } + } + enumerator->destroy(enumerator); + + fprintf(stderr, "invalid index %d\n", index); + return 1; +} + + /** * Handle PKCs#12 containers */ static int pkcs12() { - char *arg, *file = NULL; + char *arg, *file = NULL, *outform = NULL; pkcs12_t *p12 = NULL; - int res = 1; + int res = 1, index = 0; enum { OP_NONE, OP_LIST, + OP_EXPORT, } op = OP_NONE; while (TRUE) @@ -87,6 +158,17 @@ static int pkcs12() } op = OP_LIST; continue; + case 'e': + if (op != OP_NONE) + { + goto invalid; + } + op = OP_EXPORT; + index = atoi(arg); + continue; + case 'f': + outform = arg; + continue; case EOF: break; default: @@ -96,11 +178,6 @@ static int pkcs12() break; } - if (op != OP_LIST) - { - return command_usage(NULL); - } - if (file) { p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12, @@ -127,7 +204,19 @@ static int pkcs12() goto end; } - res = show(p12); + switch (op) + { + case OP_LIST: + res = show(p12); + break; + case OP_EXPORT: + res = export(p12, index, outform); + break; + default: + p12->container.destroy(&p12->container); + return command_usage(NULL); + } + end: if (p12) { @@ -143,11 +232,14 @@ static void __attribute__ ((constructor))reg() { command_register((command_t) { pkcs12, 'u', "pkcs12", "PKCS#12 functions", - {"--list [--in file]"}, + {"--export index|--list [--in file]", + "[--outform der|pem|dnskey|sshkey]"}, { {"help", 'h', 0, "show usage information"}, {"in", 'i', 1, "input file, default: stdin"}, {"list", 'l', 0, "list certificates and keys"}, + {"export", 'e', 1, "export the credential with the given index"}, + {"outform", 'f', 1, "encoding of extracted public key, default: der"}, } }); } diff --git a/src/pki/man/pki---pkcs12.1.in b/src/pki/man/pki---pkcs12.1.in index bb082a0318..470a66389b 100644 --- a/src/pki/man/pki---pkcs12.1.in +++ b/src/pki/man/pki---pkcs12.1.in @@ -13,6 +13,13 @@ pki \-\-pkcs12 \- Provides PKCS#12 functions .YS . .SY pki\ \-\-pkcs12 +.BI \-\-export\~ index +.OP \-\-in file +.OP \-\-outform encoding +.OP \-\-debug level +.YS +. +.SY pki\ \-\-pkcs12 .BI \-\-options\~ file .YS . @@ -43,6 +50,10 @@ Read command line options from \fIfile\fR. .BI "\-l, \-\-list" List certificates and keys contained in a PKCS#12 container. .TP +.BI "\-e, \-\-export " index +Export the credential with the given \fIindex\fR. Use \fI\-\-list\fR to +determine the index of certificates and keys. +.TP .BI "\-i, \-\-in " file PKCS#12 input file. If not given the input is read from \fISTDIN\fR. .