pki: Add simple PKCS#12 display command
[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
32 printf("PKCS#12 contents:\n");
33
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(" CA certificate \"%Y\"\n", cert->get_subject(cert));
42 }
43 else
44 {
45 printf(" Certificate \"%Y\"\n", cert->get_subject(cert));
46 }
47 }
48 enumerator->destroy(enumerator);
49 enumerator = pkcs12->create_key_enumerator(pkcs12);
50 while (enumerator->enumerate(enumerator, &key))
51 {
52 printf(" %N private key\n", key_type_names, key->get_type(key));
53 }
54 enumerator->destroy(enumerator);
55 return 0;
56 }
57
58 /**
59 * Handle PKCs#12 containers
60 */
61 static int pkcs12()
62 {
63 char *arg, *file = NULL;
64 pkcs12_t *p12 = NULL;
65 int res = 1;
66 enum {
67 OP_NONE,
68 OP_SHOW,
69 } op = OP_NONE;
70
71 while (TRUE)
72 {
73 switch (command_getopt(&arg))
74 {
75 case 'h':
76 return command_usage(NULL);
77 case 'i':
78 file = arg;
79 continue;
80 case 'p':
81 if (op != OP_NONE)
82 {
83 goto invalid;
84 }
85 op = OP_SHOW;
86 continue;
87 case EOF:
88 break;
89 default:
90 invalid:
91 return command_usage("invalid --pkcs12 option");
92 }
93 break;
94 }
95
96 if (op != OP_SHOW)
97 {
98 return command_usage(NULL);
99 }
100
101 if (file)
102 {
103 p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
104 BUILD_FROM_FILE, file, BUILD_END);
105 }
106 else
107 {
108 chunk_t chunk;
109
110 set_file_mode(stdin, CERT_ASN1_DER);
111 if (!chunk_from_fd(0, &chunk))
112 {
113 fprintf(stderr, "reading input failed: %s\n", strerror(errno));
114 return 1;
115 }
116 p12 = lib->creds->create(lib->creds, CRED_CONTAINER, CONTAINER_PKCS12,
117 BUILD_BLOB, chunk, BUILD_END);
118 free(chunk.ptr);
119 }
120
121 if (!p12)
122 {
123 fprintf(stderr, "reading input failed!\n");
124 goto end;
125 }
126
127 res = show(p12);
128 end:
129 if (p12)
130 {
131 p12->container.destroy(&p12->container);
132 }
133 return res;
134 }
135
136 /**
137 * Register the command.
138 */
139 static void __attribute__ ((constructor))reg()
140 {
141 command_register((command_t) {
142 pkcs12, 'u', "pkcs12", "PKCS#12 functions",
143 {"--show [--in file]"},
144 {
145 {"help", 'h', 0, "show usage information"},
146 {"show", 'p', 0, "show info about PKCS#12, print certificates and keys"},
147 {"in", 'i', 1, "input file, default: stdin"},
148 }
149 });
150 }