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>
30 #include <vici_version.h>
31 #include <vici_cert_info.h>
36 * Current certificate type info
38 static vici_cert_info_t
*current_cert_info
= NULL
;
41 * Print PEM encoding of a certificate
43 static void print_pem(certificate_t
*cert
)
47 if (cert
->get_encoding(cert
, CERT_PEM
, &encoding
))
49 printf("%.*s", (int)encoding
.len
, encoding
.ptr
);
54 fprintf(stderr
, "PEM encoding certificate failed\n");
58 CALLBACK(list_cb
, void,
59 command_format_options_t
*format
, char *name
, vici_res_t
*res
)
62 certificate_printer_t
*printer
;
63 vici_version_t version
;
64 vici_cert_info_t
*cert_info
;
65 bool detailed
, utc
, has_privkey
, first
= FALSE
;
66 char *version_str
, *type_str
;
70 if (*format
& COMMAND_FORMAT_RAW
)
72 vici_dump(res
, "list-cert event", *format
& COMMAND_FORMAT_PRETTY
,
77 version_str
= vici_find_str(res
, "1.0", "vici");
78 if (!enum_from_name(vici_version_names
, version_str
, &version
) ||
81 fprintf(stderr
, "unsupported vici version '%s'\n", version_str
);
85 buf
= vici_find(res
, &len
, "data");
88 fprintf(stderr
, "received incomplete certificate data\n");
91 has_privkey
= streq(vici_find_str(res
, "no", "has_privkey"), "yes");
93 type_str
= vici_find_str(res
, "any", "type");
94 cert_info
= vici_cert_info_retrieve(type_str
);
95 if (!cert_info
|| cert_info
->type
== CERT_ANY
)
97 fprintf(stderr
, "unsupported certificate type '%s'\n", type_str
);
101 /* Detect change of certificate type */
102 if (cert_info
!= current_cert_info
)
105 current_cert_info
= cert_info
;
108 /* Parse certificate data blob */
109 cert
= lib
->creds
->create(lib
->creds
, CRED_CERTIFICATE
, cert_info
->type
,
110 BUILD_BLOB_ASN1_DER
, chunk_create(buf
, len
),
114 if (*format
& COMMAND_FORMAT_PEM
)
122 printf("\nList of %ss:\n", cert_info
->caption
);
125 detailed
= !(*format
& COMMAND_FORMAT_SHORT
);
126 utc
= *format
& COMMAND_FORMAT_UTC
;
127 printer
= certificate_printer_create(stdout
, detailed
, utc
);
128 printer
->print(printer
, cert
, has_privkey
);
129 printer
->destroy(printer
);
135 fprintf(stderr
, "parsing certificate failed\n");
139 static int list_certs(vici_conn_t
*conn
)
143 command_format_options_t format
= COMMAND_FORMAT_NONE
;
144 char *arg
, *subject
= NULL
, *type
= NULL
;
149 switch (command_getopt(&arg
))
152 return command_usage(NULL
);
160 format
|= COMMAND_FORMAT_PEM
;
163 format
|= COMMAND_FORMAT_PRETTY
;
164 /* fall through to raw */
166 format
|= COMMAND_FORMAT_RAW
;
169 format
|= COMMAND_FORMAT_SHORT
;
172 format
|= COMMAND_FORMAT_UTC
;
177 return command_usage("invalid --list-certs option");
181 if (vici_register(conn
, "list-cert", list_cb
, &format
) != 0)
184 fprintf(stderr
, "registering for certificates failed: %s\n",
188 req
= vici_begin("list-certs");
189 vici_add_version(req
, VICI_VERSION
);
193 vici_add_key_valuef(req
, "type", "%s", type
);
197 vici_add_key_valuef(req
, "subject", "%s", subject
);
200 res
= vici_submit(req
, conn
);
204 fprintf(stderr
, "list-certs request failed: %s\n", strerror(errno
));
207 if (format
& COMMAND_FORMAT_RAW
)
209 vici_dump(res
, "list-certs reply", format
& COMMAND_FORMAT_PRETTY
,
217 * Register the command.
219 static void __attribute__ ((constructor
))reg()
221 command_register((command_t
) {
222 list_certs
, 'x', "list-certs", "list stored certificates",
223 {"[--subject <dn/san>] "
224 "[--type x509|x509ca|x509aa|x509ac|x509crl|x509ocsp|ocsp] "
225 "[--pem] [--raw|--pretty|--short|--utc]"},
227 {"help", 'h', 0, "show usage information"},
228 {"subject", 's', 1, "filter by certificate subject"},
229 {"type", 't', 1, "filter by certificate type"},
230 {"pem", 'p', 0, "print PEM encoding of certificate"},
231 {"raw", 'r', 0, "dump raw response message"},
232 {"pretty", 'P', 0, "dump raw response message in pretty print"},
233 {"short", 'S', 0, "omit some certificate details"},
234 {"utc", 'U', 0, "use UTC for time fields"},