2 * Copyright (C) 2010 Martin Willi
3 * Copyright (C) 2010 revosec AG
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>.
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
18 #include <asn1/asn1.h>
20 #include <credentials/certificates/certificate.h>
21 #include <credentials/certificates/x509.h>
22 #include <credentials/certificates/crl.h>
23 #include <credentials/certificates/ac.h>
24 #include <selectors/traffic_selector.h>
30 * Print public key information
32 static void print_pubkey(public_key_t
*key
)
36 printf("pubkey: %N %d bits\n", key_type_names
, key
->get_type(key
),
37 key
->get_keysize(key
));
38 if (key
->get_fingerprint(key
, KEYID_PUBKEY_INFO_SHA1
, &chunk
))
40 printf("keyid: %#B\n", &chunk
);
42 if (key
->get_fingerprint(key
, KEYID_PUBKEY_SHA1
, &chunk
))
44 printf("subjkey: %#B\n", &chunk
);
49 * Print private key information
51 static void print_key(private_key_t
*key
)
55 public = key
->get_public_key(key
);
58 printf("private key with:\n");
60 public->destroy(public);
64 printf("extracting public from private key failed\n");
69 * Print X509 specific certificate information
71 static void print_x509(x509_t
*x509
)
73 enumerator_t
*enumerator
;
75 traffic_selector_t
*block
;
79 int len
, explicit, inhibit
;
82 x509_cert_policy_t
*policy
;
83 x509_policy_mapping_t
*mapping
;
85 chunk
= chunk_skip_zero(x509
->get_serial(x509
));
86 printf("serial: %#B\n", &chunk
);
89 enumerator
= x509
->create_subjectAltName_enumerator(x509
);
90 while (enumerator
->enumerate(enumerator
, &id
))
107 enumerator
->destroy(enumerator
);
109 flags
= x509
->get_flags(x509
);
115 if (flags
& X509_CRL_SIGN
)
123 if (flags
& X509_OCSP_SIGNER
)
131 if (flags
& X509_SERVER_AUTH
)
133 printf("serverAuth ");
135 if (flags
& X509_CLIENT_AUTH
)
137 printf("clientAuth ");
139 if (flags
& X509_IKE_INTERMEDIATE
)
141 printf("iKEIntermediate ");
143 if (flags
& X509_MS_SMARTCARD_LOGON
)
145 printf("msSmartcardLogon ");
147 if (flags
& X509_SELF_SIGNED
)
149 printf("self-signed ");
154 enumerator
= x509
->create_crl_uri_enumerator(x509
);
155 while (enumerator
->enumerate(enumerator
, &cdp
))
159 printf("CRL URIs: %s", cdp
->uri
);
164 printf(" %s", cdp
->uri
);
168 printf(" (CRL issuer: %Y)", cdp
->issuer
);
172 enumerator
->destroy(enumerator
);
175 enumerator
= x509
->create_ocsp_uri_enumerator(x509
);
176 while (enumerator
->enumerate(enumerator
, &uri
))
180 printf("OCSP URIs: %s\n", uri
);
185 printf(" %s\n", uri
);
188 enumerator
->destroy(enumerator
);
190 len
= x509
->get_constraint(x509
, X509_PATH_LEN
);
191 if (len
!= X509_NO_CONSTRAINT
)
193 printf("pathlen: %d\n", len
);
197 enumerator
= x509
->create_name_constraint_enumerator(x509
, TRUE
);
198 while (enumerator
->enumerate(enumerator
, &id
))
202 printf("Permitted NameConstraints:\n");
207 enumerator
->destroy(enumerator
);
209 enumerator
= x509
->create_name_constraint_enumerator(x509
, FALSE
);
210 while (enumerator
->enumerate(enumerator
, &id
))
214 printf("Excluded NameConstraints:\n");
219 enumerator
->destroy(enumerator
);
222 enumerator
= x509
->create_cert_policy_enumerator(x509
);
223 while (enumerator
->enumerate(enumerator
, &policy
))
229 printf("CertificatePolicies:\n");
232 oid
= asn1_oid_to_string(policy
->oid
);
235 printf(" %s\n", oid
);
240 printf(" %#B\n", &policy
->oid
);
244 printf(" CPS: %s\n", policy
->cps_uri
);
246 if (policy
->unotice_text
)
248 printf(" Notice: %s\n", policy
->unotice_text
);
252 enumerator
->destroy(enumerator
);
255 enumerator
= x509
->create_policy_mapping_enumerator(x509
);
256 while (enumerator
->enumerate(enumerator
, &mapping
))
258 char *issuer_oid
, *subject_oid
;
262 printf("PolicyMappings:\n");
265 issuer_oid
= asn1_oid_to_string(mapping
->issuer
);
266 subject_oid
= asn1_oid_to_string(mapping
->subject
);
267 printf(" %s => %s\n", issuer_oid
, subject_oid
);
271 enumerator
->destroy(enumerator
);
273 explicit = x509
->get_constraint(x509
, X509_REQUIRE_EXPLICIT_POLICY
);
274 inhibit
= x509
->get_constraint(x509
, X509_INHIBIT_POLICY_MAPPING
);
275 len
= x509
->get_constraint(x509
, X509_INHIBIT_ANY_POLICY
);
277 if (explicit != X509_NO_CONSTRAINT
|| inhibit
!= X509_NO_CONSTRAINT
||
278 len
!= X509_NO_CONSTRAINT
)
280 printf("PolicyConstraints:\n");
281 if (explicit != X509_NO_CONSTRAINT
)
283 printf(" requireExplicitPolicy: %d\n", explicit);
285 if (inhibit
!= X509_NO_CONSTRAINT
)
287 printf(" inhibitPolicyMapping: %d\n", inhibit
);
289 if (len
!= X509_NO_CONSTRAINT
)
291 printf(" inhibitAnyPolicy: %d\n", len
);
295 chunk
= x509
->get_authKeyIdentifier(x509
);
298 printf("authkeyId: %#B\n", &chunk
);
301 chunk
= x509
->get_subjectKeyIdentifier(x509
);
304 printf("subjkeyId: %#B\n", &chunk
);
306 if (x509
->get_flags(x509
) & X509_IP_ADDR_BLOCKS
)
309 printf("addresses: ");
310 enumerator
= x509
->create_ipAddrBlock_enumerator(x509
);
311 while (enumerator
->enumerate(enumerator
, &block
))
323 enumerator
->destroy(enumerator
);
329 * Print CRL specific information
331 static void print_crl(crl_t
*crl
)
333 enumerator_t
*enumerator
;
343 chunk
= chunk_skip_zero(crl
->get_serial(crl
));
344 printf("serial: %#B\n", &chunk
);
346 if (crl
->is_delta_crl(crl
, &chunk
))
348 chunk
= chunk_skip_zero(chunk
);
349 printf("delta CRL: for serial %#B\n", &chunk
);
351 chunk
= crl
->get_authKeyIdentifier(crl
);
352 printf("authKeyId: %#B\n", &chunk
);
355 enumerator
= crl
->create_delta_crl_uri_enumerator(crl
);
356 while (enumerator
->enumerate(enumerator
, &cdp
))
360 printf("freshest: %s", cdp
->uri
);
365 printf(" %s", cdp
->uri
);
369 printf(" (CRL issuer: %Y)", cdp
->issuer
);
373 enumerator
->destroy(enumerator
);
375 enumerator
= crl
->create_enumerator(crl
);
376 while (enumerator
->enumerate(enumerator
, &chunk
, &ts
, &reason
))
380 enumerator
->destroy(enumerator
);
382 printf("%d revoked certificate%s%s\n", count
,
383 count
== 1 ?
"" : "s", count ?
":" : "");
384 enumerator
= crl
->create_enumerator(crl
);
385 while (enumerator
->enumerate(enumerator
, &chunk
, &ts
, &reason
))
387 chunk
= chunk_skip_zero(chunk
);
388 localtime_r(&ts
, &tm
);
389 strftime(buf
, sizeof(buf
), "%F %T", &tm
);
390 printf(" %#B %N %s\n", &chunk
, crl_reason_names
, reason
, buf
);
393 enumerator
->destroy(enumerator
);
397 * Print AC specific information
399 static void print_ac(ac_t
*ac
)
401 ac_group_type_t type
;
402 identification_t
*id
;
403 enumerator_t
*groups
;
407 chunk
= chunk_skip_zero(ac
->get_serial(ac
));
408 printf("serial: %#B\n", &chunk
);
410 id
= ac
->get_holderIssuer(ac
);
413 printf("hissuer: \"%Y\"\n", id
);
415 chunk
= chunk_skip_zero(ac
->get_holderSerial(ac
));
418 printf("hserial: %#B\n", &chunk
);
420 groups
= ac
->create_group_enumerator(ac
);
421 while (groups
->enumerate(groups
, &type
, &chunk
))
437 case AC_GROUP_TYPE_STRING
:
438 printf("%.*s", (int)chunk
.len
, chunk
.ptr
);
440 case AC_GROUP_TYPE_OID
:
441 oid
= asn1_known_oid(chunk
);
442 if (oid
== OID_UNKNOWN
)
444 str
= asn1_oid_to_string(chunk
);
451 printf("OID:%#B", &chunk
);
456 printf("%s", oid_names
[oid
].name
);
459 case AC_GROUP_TYPE_OCTETS
:
460 printf("%#B", &chunk
);
465 groups
->destroy(groups
);
467 chunk
= ac
->get_authKeyIdentifier(ac
);
470 printf("authkey: %#B\n", &chunk
);
475 * Print certificate information
477 static void print_cert(certificate_t
*cert
)
479 time_t now
, notAfter
, notBefore
;
484 printf("cert: %N\n", certificate_type_names
, cert
->get_type(cert
));
485 if (cert
->get_type(cert
) != CERT_X509_CRL
)
487 printf("subject: \"%Y\"\n", cert
->get_subject(cert
));
489 printf("issuer: \"%Y\"\n", cert
->get_issuer(cert
));
491 cert
->get_validity(cert
, &now
, ¬Before
, ¬After
);
492 printf("validity: not before %T, ", ¬Before
, FALSE
);
495 printf("not valid yet (valid in %V)\n", &now
, ¬Before
);
501 printf(" not after %T, ", ¬After
, FALSE
);
504 printf("expired (%V ago)\n", &now
, ¬After
);
508 printf("ok (expires in %V)\n", &now
, ¬After
);
511 switch (cert
->get_type(cert
))
514 print_x509((x509_t
*)cert
);
517 print_crl((crl_t
*)cert
);
520 print_ac((ac_t
*)cert
);
523 printf("parsing certificate subtype %N not implemented\n",
524 certificate_type_names
, cert
->get_type(cert
));
527 key
= cert
->get_public_key(cert
);
536 * Print a credential in a human readable form
540 credential_type_t type
= CRED_CERTIFICATE
;
541 int subtype
= CERT_X509
;
543 char *arg
, *file
= NULL
;
547 switch (command_getopt(&arg
))
550 return command_usage(NULL
);
552 if (streq(arg
, "x509"))
554 type
= CRED_CERTIFICATE
;
557 else if (streq(arg
, "crl"))
559 type
= CRED_CERTIFICATE
;
560 subtype
= CERT_X509_CRL
;
562 else if (streq(arg
, "ac"))
564 type
= CRED_CERTIFICATE
;
565 subtype
= CERT_X509_AC
;
567 else if (streq(arg
, "pub"))
569 type
= CRED_PUBLIC_KEY
;
572 else if (streq(arg
, "rsa-priv"))
574 type
= CRED_PRIVATE_KEY
;
577 else if (streq(arg
, "ecdsa-priv"))
579 type
= CRED_PRIVATE_KEY
;
584 return command_usage( "invalid input type");
593 return command_usage("invalid --print option");
599 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
600 BUILD_FROM_FILE
, file
, BUILD_END
);
606 if (!chunk_from_fd(0, &chunk
))
608 fprintf(stderr
, "reading input failed: %s\n", strerror(errno
));
611 cred
= lib
->creds
->create(lib
->creds
, type
, subtype
,
612 BUILD_BLOB
, chunk
, BUILD_END
);
617 fprintf(stderr
, "parsing input failed\n");
621 if (type
== CRED_CERTIFICATE
)
623 certificate_t
*cert
= (certificate_t
*)cred
;
628 if (type
== CRED_PUBLIC_KEY
)
630 public_key_t
*key
= (public_key_t
*)cred
;
635 if (type
== CRED_PRIVATE_KEY
)
637 private_key_t
*key
= (private_key_t
*)cred
;
646 * Register the command.
648 static void __attribute__ ((constructor
))reg()
650 command_register((command_t
)
651 { print
, 'a', "print",
652 "print a credential in a human readable form",
653 {"[--in file] [--type rsa-priv|ecdsa-priv|pub|x509|crl|ac]"},
655 {"help", 'h', 0, "show usage information"},
656 {"in", 'i', 1, "input file, default: stdin"},
657 {"type", 't', 1, "type of credential, default: x509"},