4dcc4718e58f4da20c818a2ad56db2ac7c88400e
[strongswan.git] / src / pki / commands / print.c
1 /*
2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
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 "pki.h"
17
18 #include <credentials/certificates/certificate.h>
19 #include <credentials/certificates/x509.h>
20 #include <credentials/certificates/crl.h>
21 #include <selectors/traffic_selector.h>
22
23 #include <time.h>
24
25 /**
26 * Print public key information
27 */
28 static void print_pubkey(public_key_t *key)
29 {
30 chunk_t chunk;
31
32 printf("pubkey: %N %d bits\n", key_type_names, key->get_type(key),
33 key->get_keysize(key));
34 if (key->get_fingerprint(key, KEYID_PUBKEY_INFO_SHA1, &chunk))
35 {
36 printf("keyid: %#B\n", &chunk);
37 }
38 if (key->get_fingerprint(key, KEYID_PUBKEY_SHA1, &chunk))
39 {
40 printf("subjkey: %#B\n", &chunk);
41 }
42 }
43
44 /**
45 * Print private key information
46 */
47 static void print_key(private_key_t *key)
48 {
49 public_key_t *public;
50
51 public = key->get_public_key(key);
52 if (public)
53 {
54 printf("private key with:\n");
55 print_pubkey(public);
56 public->destroy(public);
57 }
58 else
59 {
60 printf("extracting public from private key failed\n");
61 }
62 }
63
64 /**
65 * Print X509 specific certificate information
66 */
67 static void print_x509(x509_t *x509)
68 {
69 enumerator_t *enumerator;
70 identification_t *id;
71 traffic_selector_t *block;
72 chunk_t chunk;
73 bool first;
74 char *uri;
75 int len;
76 x509_flag_t flags;
77
78 chunk = x509->get_serial(x509);
79 printf("serial: %#B\n", &chunk);
80
81 first = TRUE;
82 enumerator = x509->create_subjectAltName_enumerator(x509);
83 while (enumerator->enumerate(enumerator, &id))
84 {
85 if (first)
86 {
87 printf("altNames: ");
88 first = FALSE;
89 }
90 else
91 {
92 printf(", ");
93 }
94 printf("%Y", id);
95 }
96 if (!first)
97 {
98 printf("\n");
99 }
100 enumerator->destroy(enumerator);
101
102 flags = x509->get_flags(x509);
103 printf("flags: ");
104 if (flags & X509_CA)
105 {
106 printf("CA ");
107 }
108 if (flags & X509_AA)
109 {
110 printf("AA ");
111 }
112 if (flags & X509_OCSP_SIGNER)
113 {
114 printf("OCSP ");
115 }
116 if (flags & X509_AA)
117 {
118 printf("AA ");
119 }
120 if (flags & X509_SERVER_AUTH)
121 {
122 printf("serverAuth ");
123 }
124 if (flags & X509_CLIENT_AUTH)
125 {
126 printf("clientAuth ");
127 }
128 if (flags & X509_SELF_SIGNED)
129 {
130 printf("self-signed ");
131 }
132 printf("\n");
133
134 first = TRUE;
135 enumerator = x509->create_crl_uri_enumerator(x509);
136 while (enumerator->enumerate(enumerator, &uri, &id))
137 {
138 if (first)
139 {
140 printf("CRL URIs: %s", uri);
141 first = FALSE;
142 }
143 else
144 {
145 printf(" %s", uri);
146 }
147 if (id)
148 {
149 printf(" (CRL issuer: %Y)", id);
150 }
151 printf("\n");
152 }
153 enumerator->destroy(enumerator);
154
155 first = TRUE;
156 enumerator = x509->create_ocsp_uri_enumerator(x509);
157 while (enumerator->enumerate(enumerator, &uri))
158 {
159 if (first)
160 {
161 printf("OCSP URIs: %s\n", uri);
162 first = FALSE;
163 }
164 else
165 {
166 printf(" %s\n", uri);
167 }
168 }
169 enumerator->destroy(enumerator);
170
171 len = x509->get_pathLenConstraint(x509);
172 if (len != X509_NO_PATH_LEN_CONSTRAINT)
173 {
174 printf("pathlen: %d\n", len);
175 }
176
177 chunk = x509->get_authKeyIdentifier(x509);
178 if (chunk.ptr)
179 {
180 printf("authkeyId: %#B\n", &chunk);
181 }
182
183 chunk = x509->get_subjectKeyIdentifier(x509);
184 if (chunk.ptr)
185 {
186 printf("subjkeyId: %#B\n", &chunk);
187 }
188 if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS)
189 {
190 first = TRUE;
191 printf("addresses: ");
192 enumerator = x509->create_ipAddrBlock_enumerator(x509);
193 while (enumerator->enumerate(enumerator, &block))
194 {
195 if (first)
196 {
197 first = FALSE;
198 }
199 else
200 {
201 printf(", ");
202 }
203 printf("%R", block);
204 }
205 enumerator->destroy(enumerator);
206 printf("\n");
207 }
208 }
209
210 /**
211 * Print CRL specific information
212 */
213 static void print_crl(crl_t *crl)
214 {
215 enumerator_t *enumerator;
216 time_t ts;
217 crl_reason_t reason;
218 chunk_t chunk;
219 int count = 0;
220 char buf[64];
221 struct tm tm;
222
223 chunk = crl->get_serial(crl);
224 printf("serial: %#B\n", &chunk);
225 chunk = crl->get_authKeyIdentifier(crl);
226 printf("authKeyId: %#B\n", &chunk);
227
228 enumerator = crl->create_enumerator(crl);
229 while (enumerator->enumerate(enumerator, &chunk, &ts, &reason))
230 {
231 count++;
232 }
233 enumerator->destroy(enumerator);
234
235 printf("%d revoked certificate%s%s\n", count,
236 count == 1 ? "" : "s", count ? ":" : "");
237 enumerator = crl->create_enumerator(crl);
238 while (enumerator->enumerate(enumerator, &chunk, &ts, &reason))
239 {
240 localtime_r(&ts, &tm);
241 strftime(buf, sizeof(buf), "%F %T", &tm);
242 printf(" %#B %N %s\n", &chunk, crl_reason_names, reason, buf);
243 count++;
244 }
245 enumerator->destroy(enumerator);
246 }
247
248 /**
249 * Print certificate information
250 */
251 static void print_cert(certificate_t *cert)
252 {
253 time_t now, notAfter, notBefore;
254 public_key_t *key;
255
256 now = time(NULL);
257
258 printf("cert: %N\n", certificate_type_names, cert->get_type(cert));
259 if (cert->get_type(cert) != CERT_X509_CRL)
260 {
261 printf("subject: \"%Y\"\n", cert->get_subject(cert));
262 }
263 printf("issuer: \"%Y\"\n", cert->get_issuer(cert));
264
265 cert->get_validity(cert, &now, &notBefore, &notAfter);
266 printf("validity: not before %T, ", &notBefore, FALSE);
267 if (now < notBefore)
268 {
269 printf("not valid yet (valid in %V)\n", &now, &notBefore);
270 }
271 else
272 {
273 printf("ok\n");
274 }
275 printf(" not after %T, ", &notAfter, FALSE);
276 if (now > notAfter)
277 {
278 printf("expired (%V ago)\n", &now, &notAfter);
279 }
280 else
281 {
282 printf("ok (expires in %V)\n", &now, &notAfter);
283 }
284
285 switch (cert->get_type(cert))
286 {
287 case CERT_X509:
288 print_x509((x509_t*)cert);
289 break;
290 case CERT_X509_CRL:
291 print_crl((crl_t*)cert);
292 break;
293 default:
294 printf("parsing certificate subtype %N not implemented\n",
295 certificate_type_names, cert->get_type(cert));
296 break;
297 }
298 key = cert->get_public_key(cert);
299 if (key)
300 {
301 print_pubkey(key);
302 key->destroy(key);
303 }
304 }
305
306 /**
307 * Print a credential in a human readable form
308 */
309 static int print()
310 {
311 credential_type_t type = CRED_CERTIFICATE;
312 int subtype = CERT_X509;
313 void *cred;
314 char *arg, *file = NULL;
315
316 while (TRUE)
317 {
318 switch (command_getopt(&arg))
319 {
320 case 'h':
321 return command_usage(NULL);
322 case 't':
323 if (streq(arg, "x509"))
324 {
325 type = CRED_CERTIFICATE;
326 subtype = CERT_X509;
327 }
328 else if (streq(arg, "crl"))
329 {
330 type = CRED_CERTIFICATE;
331 subtype = CERT_X509_CRL;
332 }
333 else if (streq(arg, "pub"))
334 {
335 type = CRED_PUBLIC_KEY;
336 subtype = KEY_ANY;
337 }
338 else if (streq(arg, "rsa-priv"))
339 {
340 type = CRED_PRIVATE_KEY;
341 subtype = KEY_RSA;
342 }
343 else if (streq(arg, "ecdsa-priv"))
344 {
345 type = CRED_PRIVATE_KEY;
346 subtype = KEY_ECDSA;
347 }
348 else
349 {
350 return command_usage( "invalid input type");
351 }
352 continue;
353 case 'i':
354 file = arg;
355 continue;
356 case EOF:
357 break;
358 default:
359 return command_usage("invalid --print option");
360 }
361 break;
362 }
363 if (file)
364 {
365 cred = lib->creds->create(lib->creds, type, subtype,
366 BUILD_FROM_FILE, file, BUILD_END);
367 }
368 else
369 {
370 cred = lib->creds->create(lib->creds, type, subtype,
371 BUILD_FROM_FD, 0, BUILD_END);
372 }
373 if (!cred)
374 {
375 fprintf(stderr, "parsing input failed\n");
376 return 1;
377 }
378
379 if (type == CRED_CERTIFICATE)
380 {
381 certificate_t *cert = (certificate_t*)cred;
382
383 print_cert(cert);
384 cert->destroy(cert);
385 }
386 if (type == CRED_PUBLIC_KEY)
387 {
388 public_key_t *key = (public_key_t*)cred;
389
390 print_pubkey(key);
391 key->destroy(key);
392 }
393 if (type == CRED_PRIVATE_KEY)
394 {
395 private_key_t *key = (private_key_t*)cred;
396
397 print_key(key);
398 key->destroy(key);
399 }
400 return 0;
401 }
402
403 /**
404 * Register the command.
405 */
406 static void __attribute__ ((constructor))reg()
407 {
408 command_register((command_t)
409 { print, 'a', "print",
410 "print a credential in a human readable form",
411 {"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509|crl]"},
412 {
413 {"help", 'h', 0, "show usage information"},
414 {"in", 'i', 1, "input file, default: stdin"},
415 {"type", 't', 1, "type of credential, default: x509"},
416 }
417 });
418 }