pki: Reformat PKCS#12 output and add an index for each certificate/key
[strongswan.git] / src / pki / commands / pkcs12.c
1 /*
2 * Copyright (C) 2014 Tobias Brunner
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include <errno.h>
17
18 #include "pki.h"
19
20 #include <credentials/certificates/x509.h>
21 #include <credentials/containers/pkcs12.h>
22
23 /**
24 * Show info about PKCS#12 container
25 */
26 static int show(pkcs12_t *pkcs12)
27 {
28 enumerator_t *enumerator;
29 certificate_t *cert;
30 private_key_t *key;
31 int index = 1;
32
33 printf("Certificates:\n");
34 enumerator = pkcs12->create_cert_enumerator(pkcs12);
35 while (enumerator->enumerate(enumerator, &cert))
36 {
37 x509_t *x509 = (x509_t*)cert;
38
39 if (x509->get_flags(x509) & X509_CA)
40 {
41 printf("[%2d] \"%Y\" (CA)\n", index++, cert->get_subject(cert));
42 }
43 else
44 {
45 printf("[%2d] \"%Y\"\n", index++, cert->get_subject(cert));
46 }
47 }
48 enumerator->destroy(enumerator);
49
50 printf("Private keys:\n");
51 enumerator = pkcs12->create_key_enumerator(pkcs12);
52 while (enumerator->enumerate(enumerator, &key))
53 {
54 printf("[%2d] %N %d bits\n", index++, key_type_names,
55 key->get_type(key), key->get_keysize(key));
56 }
57 enumerator->destroy(enumerator);
58 return 0;
59 }
60
61 /**
62 * Handle PKCs#12 containers
63 */
64 static int pkcs12()
65 {
66 char *arg, *file = NULL;
67 pkcs12_t *p12 = NULL;
68 int res = 1;
69 enum {
70 OP_NONE,
71 OP_LIST,
72 } op = OP_NONE;
73
74 while (TRUE)
75 {
76 switch (command_getopt(&arg))
77 {
78 case 'h':
79 return command_usage(NULL);
80 case 'i':
81 file = arg;
82 continue;
83 case 'l':
84 if (op != OP_NONE)
85 {
86 goto invalid;
87 }
88 op = OP_LIST;
89 continue;
90 case EOF:
91 break;
92 default:
93 invalid:
94 return command_usage("invalid --pkcs12 option");
95 }
96 break;
97 }
98
99 if (op != OP_LIST)
100 {
101 return command_usage(NULL);
102 }
103
104 if (file)
105 {
106 p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
107 BUILD_FROM_FILE, file, BUILD_END);
108 }
109 else
110 {
111 chunk_t chunk;
112
113 set_file_mode(stdin, CERT_ASN1_DER);
114 if (!chunk_from_fd(0, &chunk))
115 {
116 fprintf(stderr, "reading input failed: %s\n", strerror(errno));
117 return 1;
118 }
119 p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
120 BUILD_BLOB, chunk, BUILD_END);
121 free(chunk.ptr);
122 }
123
124 if (!p12)
125 {
126 fprintf(stderr, "reading input failed!\n");
127 goto end;
128 }
129
130 res = show(p12);
131 end:
132 if (p12)
133 {
134 p12->container.destroy(&p12->container);
135 }
136 return res;
137 }
138
139 /**
140 * Register the command.
141 */
142 static void __attribute__ ((constructor))reg()
143 {
144 command_register((command_t) {
145 pkcs12, 'u', "pkcs12", "PKCS#12 functions",
146 {"--list [--in file]"},
147 {
148 {"help", 'h', 0, "show usage information"},
149 {"in", 'i', 1, "input file, default: stdin"},
150 {"list", 'l', 0, "list certificates and keys"},
151 }
152 });
153 }