2 * Copyright (C) 2014 Martin Willi
3 * Copyright (C) 2014 revosec AG
5 * Copyright (C) 2015 Andreas Steffen
6 * HSR Hochschule fuer Technik Rapperswil
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 #include <asn1/asn1.h>
26 #include <credentials/certificates/certificate.h>
27 #include <credentials/certificates/certificate_printer.h>
28 #include <selectors/traffic_selector.h>
33 * Static certificate printer object
35 static certificate_printer_t
*cert_printer
= NULL
;
38 * Print PEM encoding of a certificate
40 static void print_pem(certificate_t
*cert
)
44 if (cert
->get_encoding(cert
, CERT_PEM
, &encoding
))
46 printf("%.*s", (int)encoding
.len
, encoding
.ptr
);
51 fprintf(stderr
, "PEM encoding certificate failed\n");
55 CALLBACK(list_cb
, void,
56 command_format_options_t
*format
, char *name
, vici_res_t
*res
)
59 certificate_type_t type
;
60 x509_flag_t flag
= X509_NONE
;
66 if (*format
& COMMAND_FORMAT_RAW
)
68 vici_dump(res
, "list-cert event", *format
& COMMAND_FORMAT_PRETTY
,
73 buf
= vici_find(res
, &len
, "data");
76 fprintf(stderr
, "received incomplete certificate data\n");
79 has_privkey
= streq(vici_find_str(res
, "no", "has_privkey"), "yes");
81 str
= vici_find_str(res
, "ANY", "type");
82 if (!enum_from_name(certificate_type_names
, str
, &type
) || type
== CERT_ANY
)
84 fprintf(stderr
, "unsupported certificate type '%s'\n", str
);
87 if (type
== CERT_X509
)
89 str
= vici_find_str(res
, "ANY", "flag");
90 if (!enum_from_name(x509_flag_names
, str
, &flag
) || flag
== X509_ANY
)
92 fprintf(stderr
, "unsupported certificate flag '%s'\n", str
);
97 /* Parse certificate data blob */
98 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, type
,
99 BUILD_BLOB_ASN1_DER
, chunk_create(buf
, len
),
103 if (*format
& COMMAND_FORMAT_PEM
)
109 cert_printer
->print_caption(cert_printer
, type
, flag
);
110 cert_printer
->print(cert_printer
, cert
, has_privkey
);
116 fprintf(stderr
, "parsing certificate failed\n");
120 static int list_certs(vici_conn_t
*conn
)
124 command_format_options_t format
= COMMAND_FORMAT_NONE
;
125 char *arg
, *subject
= NULL
, *type
= NULL
, *flag
= NULL
;
126 bool detailed
= TRUE
, utc
= FALSE
;
131 switch (command_getopt(&arg
))
134 return command_usage(NULL
);
145 format
|= COMMAND_FORMAT_PEM
;
148 format
|= COMMAND_FORMAT_PRETTY
;
149 /* fall through to raw */
151 format
|= COMMAND_FORMAT_RAW
;
162 return command_usage("invalid --list-certs option");
166 if (vici_register(conn
, "list-cert", list_cb
, &format
) != 0)
169 fprintf(stderr
, "registering for certificates failed: %s\n",
173 req
= vici_begin("list-certs");
177 vici_add_key_valuef(req
, "type", "%s", type
);
181 vici_add_key_valuef(req
, "flag", "%s", flag
);
185 vici_add_key_valuef(req
, "subject", "%s", subject
);
187 cert_printer
= certificate_printer_create(stdout
, detailed
, utc
);
189 res
= vici_submit(req
, conn
);
193 fprintf(stderr
, "list-certs request failed: %s\n", strerror(errno
));
194 cert_printer
->destroy(cert_printer
);
198 if (format
& COMMAND_FORMAT_RAW
)
200 vici_dump(res
, "list-certs reply", format
& COMMAND_FORMAT_PRETTY
,
205 cert_printer
->destroy(cert_printer
);
211 * Register the command.
213 static void __attribute__ ((constructor
))reg()
215 command_register((command_t
) {
216 list_certs
, 'x', "list-certs", "list stored certificates",
217 {"[--subject <dn/san>] [--pem]",
218 "[--type x509|x509_ac|x509_crl|ocsp_response|pubkey]",
219 "[--flag none|ca|aa|ocsp|any] [--raw|--pretty|--short|--utc]"},
221 {"help", 'h', 0, "show usage information"},
222 {"subject", 's', 1, "filter by certificate subject"},
223 {"type", 't', 1, "filter by certificate type"},
224 {"flag", 'f', 1, "filter by X.509 certificate flag"},
225 {"pem", 'p', 0, "print PEM encoding of certificate"},
226 {"raw", 'r', 0, "dump raw response message"},
227 {"pretty", 'P', 0, "dump raw response message in pretty print"},
228 {"short", 'S', 0, "omit some certificate details"},
229 {"utc", 'U', 0, "use UTC for time fields"},