pki tool shows and builds crlSign keyUsage
[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_CRL_SIGN)
109 {
110 printf("CRLSign ");
111 }
112 if (flags & X509_AA)
113 {
114 printf("AA ");
115 }
116 if (flags & X509_OCSP_SIGNER)
117 {
118 printf("OCSP ");
119 }
120 if (flags & X509_AA)
121 {
122 printf("AA ");
123 }
124 if (flags & X509_SERVER_AUTH)
125 {
126 printf("serverAuth ");
127 }
128 if (flags & X509_CLIENT_AUTH)
129 {
130 printf("clientAuth ");
131 }
132 if (flags & X509_SELF_SIGNED)
133 {
134 printf("self-signed ");
135 }
136 printf("\n");
137
138 first = TRUE;
139 enumerator = x509->create_crl_uri_enumerator(x509);
140 while (enumerator->enumerate(enumerator, &uri, &id))
141 {
142 if (first)
143 {
144 printf("CRL URIs: %s", uri);
145 first = FALSE;
146 }
147 else
148 {
149 printf(" %s", uri);
150 }
151 if (id)
152 {
153 printf(" (CRL issuer: %Y)", id);
154 }
155 printf("\n");
156 }
157 enumerator->destroy(enumerator);
158
159 first = TRUE;
160 enumerator = x509->create_ocsp_uri_enumerator(x509);
161 while (enumerator->enumerate(enumerator, &uri))
162 {
163 if (first)
164 {
165 printf("OCSP URIs: %s\n", uri);
166 first = FALSE;
167 }
168 else
169 {
170 printf(" %s\n", uri);
171 }
172 }
173 enumerator->destroy(enumerator);
174
175 len = x509->get_pathLenConstraint(x509);
176 if (len != X509_NO_PATH_LEN_CONSTRAINT)
177 {
178 printf("pathlen: %d\n", len);
179 }
180
181 chunk = x509->get_authKeyIdentifier(x509);
182 if (chunk.ptr)
183 {
184 printf("authkeyId: %#B\n", &chunk);
185 }
186
187 chunk = x509->get_subjectKeyIdentifier(x509);
188 if (chunk.ptr)
189 {
190 printf("subjkeyId: %#B\n", &chunk);
191 }
192 if (x509->get_flags(x509) & X509_IP_ADDR_BLOCKS)
193 {
194 first = TRUE;
195 printf("addresses: ");
196 enumerator = x509->create_ipAddrBlock_enumerator(x509);
197 while (enumerator->enumerate(enumerator, &block))
198 {
199 if (first)
200 {
201 first = FALSE;
202 }
203 else
204 {
205 printf(", ");
206 }
207 printf("%R", block);
208 }
209 enumerator->destroy(enumerator);
210 printf("\n");
211 }
212 }
213
214 /**
215 * Print CRL specific information
216 */
217 static void print_crl(crl_t *crl)
218 {
219 enumerator_t *enumerator;
220 time_t ts;
221 crl_reason_t reason;
222 chunk_t chunk;
223 int count = 0;
224 char buf[64];
225 struct tm tm;
226
227 chunk = crl->get_serial(crl);
228 printf("serial: %#B\n", &chunk);
229 chunk = crl->get_authKeyIdentifier(crl);
230 printf("authKeyId: %#B\n", &chunk);
231
232 enumerator = crl->create_enumerator(crl);
233 while (enumerator->enumerate(enumerator, &chunk, &ts, &reason))
234 {
235 count++;
236 }
237 enumerator->destroy(enumerator);
238
239 printf("%d revoked certificate%s%s\n", count,
240 count == 1 ? "" : "s", count ? ":" : "");
241 enumerator = crl->create_enumerator(crl);
242 while (enumerator->enumerate(enumerator, &chunk, &ts, &reason))
243 {
244 localtime_r(&ts, &tm);
245 strftime(buf, sizeof(buf), "%F %T", &tm);
246 printf(" %#B %N %s\n", &chunk, crl_reason_names, reason, buf);
247 count++;
248 }
249 enumerator->destroy(enumerator);
250 }
251
252 /**
253 * Print certificate information
254 */
255 static void print_cert(certificate_t *cert)
256 {
257 time_t now, notAfter, notBefore;
258 public_key_t *key;
259
260 now = time(NULL);
261
262 printf("cert: %N\n", certificate_type_names, cert->get_type(cert));
263 if (cert->get_type(cert) != CERT_X509_CRL)
264 {
265 printf("subject: \"%Y\"\n", cert->get_subject(cert));
266 }
267 printf("issuer: \"%Y\"\n", cert->get_issuer(cert));
268
269 cert->get_validity(cert, &now, &notBefore, &notAfter);
270 printf("validity: not before %T, ", &notBefore, FALSE);
271 if (now < notBefore)
272 {
273 printf("not valid yet (valid in %V)\n", &now, &notBefore);
274 }
275 else
276 {
277 printf("ok\n");
278 }
279 printf(" not after %T, ", &notAfter, FALSE);
280 if (now > notAfter)
281 {
282 printf("expired (%V ago)\n", &now, &notAfter);
283 }
284 else
285 {
286 printf("ok (expires in %V)\n", &now, &notAfter);
287 }
288
289 switch (cert->get_type(cert))
290 {
291 case CERT_X509:
292 print_x509((x509_t*)cert);
293 break;
294 case CERT_X509_CRL:
295 print_crl((crl_t*)cert);
296 break;
297 default:
298 printf("parsing certificate subtype %N not implemented\n",
299 certificate_type_names, cert->get_type(cert));
300 break;
301 }
302 key = cert->get_public_key(cert);
303 if (key)
304 {
305 print_pubkey(key);
306 key->destroy(key);
307 }
308 }
309
310 /**
311 * Print a credential in a human readable form
312 */
313 static int print()
314 {
315 credential_type_t type = CRED_CERTIFICATE;
316 int subtype = CERT_X509;
317 void *cred;
318 char *arg, *file = NULL;
319
320 while (TRUE)
321 {
322 switch (command_getopt(&arg))
323 {
324 case 'h':
325 return command_usage(NULL);
326 case 't':
327 if (streq(arg, "x509"))
328 {
329 type = CRED_CERTIFICATE;
330 subtype = CERT_X509;
331 }
332 else if (streq(arg, "crl"))
333 {
334 type = CRED_CERTIFICATE;
335 subtype = CERT_X509_CRL;
336 }
337 else if (streq(arg, "pub"))
338 {
339 type = CRED_PUBLIC_KEY;
340 subtype = KEY_ANY;
341 }
342 else if (streq(arg, "rsa-priv"))
343 {
344 type = CRED_PRIVATE_KEY;
345 subtype = KEY_RSA;
346 }
347 else if (streq(arg, "ecdsa-priv"))
348 {
349 type = CRED_PRIVATE_KEY;
350 subtype = KEY_ECDSA;
351 }
352 else
353 {
354 return command_usage( "invalid input type");
355 }
356 continue;
357 case 'i':
358 file = arg;
359 continue;
360 case EOF:
361 break;
362 default:
363 return command_usage("invalid --print option");
364 }
365 break;
366 }
367 if (file)
368 {
369 cred = lib->creds->create(lib->creds, type, subtype,
370 BUILD_FROM_FILE, file, BUILD_END);
371 }
372 else
373 {
374 cred = lib->creds->create(lib->creds, type, subtype,
375 BUILD_FROM_FD, 0, BUILD_END);
376 }
377 if (!cred)
378 {
379 fprintf(stderr, "parsing input failed\n");
380 return 1;
381 }
382
383 if (type == CRED_CERTIFICATE)
384 {
385 certificate_t *cert = (certificate_t*)cred;
386
387 print_cert(cert);
388 cert->destroy(cert);
389 }
390 if (type == CRED_PUBLIC_KEY)
391 {
392 public_key_t *key = (public_key_t*)cred;
393
394 print_pubkey(key);
395 key->destroy(key);
396 }
397 if (type == CRED_PRIVATE_KEY)
398 {
399 private_key_t *key = (private_key_t*)cred;
400
401 print_key(key);
402 key->destroy(key);
403 }
404 return 0;
405 }
406
407 /**
408 * Register the command.
409 */
410 static void __attribute__ ((constructor))reg()
411 {
412 command_register((command_t)
413 { print, 'a', "print",
414 "print a credential in a human readable form",
415 {"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509|crl]"},
416 {
417 {"help", 'h', 0, "show usage information"},
418 {"in", 'i', 1, "input file, default: stdin"},
419 {"type", 't', 1, "type of credential, default: x509"},
420 }
421 });
422 }