vici: list-cert sends subject, not-before and not-after attributes for pubkeys
[strongswan.git] / src / swanctl / commands / list_certs.c
index f3821a5..e9c9647 100644 (file)
 #include <credentials/certificates/certificate_printer.h>
 #include <selectors/traffic_selector.h>
 
-#include <vici_version.h>
-#include <vici_cert_info.h>
-
 #include "command.h"
 
 /**
- * Current certificate type info
+ * Static certificate printer object
  */
-static vici_cert_info_t *current_cert_info = NULL;
+static certificate_printer_t *cert_printer = NULL;
 
 /**
  * Print PEM encoding of a certificate
@@ -59,11 +56,14 @@ CALLBACK(list_cb, void,
        command_format_options_t *format, char *name, vici_res_t *res)
 {
        certificate_t *cert;
-       certificate_printer_t *printer;
-       vici_version_t version;
-       vici_cert_info_t *cert_info;
-       bool detailed, utc, has_privkey, first = FALSE;
-       char *version_str, *type_str;
+       certificate_type_t type;
+       x509_flag_t flag = X509_NONE;
+       identification_t *subject = NULL;
+       time_t not_before = UNDEFINED_TIME;
+       time_t not_after  = UNDEFINED_TIME;
+       chunk_t t_ch;
+       bool has_privkey;
+       char *str;
        void *buf;
        int len;
 
@@ -74,14 +74,6 @@ CALLBACK(list_cb, void,
                return;
        }
 
-       version_str = vici_find_str(res, "1.0", "vici");
-       if (!enum_from_name(vici_version_names, version_str, &version) ||
-               version == VICI_1_0)
-       {
-               fprintf(stderr, "unsupported vici version '%s'\n", version_str);
-               return;
-       }
-
        buf = vici_find(res, &len, "data");
        if (!buf)
        {
@@ -90,25 +82,53 @@ CALLBACK(list_cb, void,
        }
        has_privkey = streq(vici_find_str(res, "no", "has_privkey"), "yes");
 
-       type_str = vici_find_str(res, "any", "type");
-       cert_info = vici_cert_info_retrieve(type_str);
-       if (!cert_info || cert_info->type == CERT_ANY)
+       str = vici_find_str(res, "ANY", "type");
+       if (!enum_from_name(certificate_type_names, str, &type) || type == CERT_ANY)
        {
-               fprintf(stderr, "unsupported certificate type '%s'\n", type_str);
+               fprintf(stderr, "unsupported certificate type '%s'\n", str);
                return;
        }
-
-       /* Detect change of certificate type */
-       if (cert_info != current_cert_info)
+       if (type == CERT_X509)
        {
-               first = TRUE;
-               current_cert_info = cert_info;
+               str = vici_find_str(res, "ANY", "flag");
+               if (!enum_from_name(x509_flag_names, str, &flag) || flag == X509_ANY)
+               {
+                       fprintf(stderr, "unsupported certificate flag '%s'\n", str);
+                       return;
+               }
+       }
+       if (type == CERT_TRUSTED_PUBKEY)
+       {
+               str = vici_find_str(res, NULL, "subject");
+               if (str)
+               {
+                       subject = identification_create_from_string(str);
+               }
+               str = vici_find_str(res, NULL, "not-before");
+               if (str)
+               {
+                       t_ch = chunk_from_str(str);
+                       not_before = asn1_to_time(&t_ch, ASN1_GENERALIZEDTIME);
+               }
+               str = vici_find_str(res, NULL, "not-after");
+               if (str)
+               {
+                       t_ch = chunk_from_str(str);
+                       not_after = asn1_to_time(&t_ch, ASN1_GENERALIZEDTIME);
+               }
+               cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
+                                                                 BUILD_BLOB_ASN1_DER, chunk_create(buf, len),
+                                                                 BUILD_NOT_BEFORE_TIME, not_before,
+                                                                 BUILD_NOT_AFTER_TIME, not_after,
+                                                                 BUILD_SUBJECT, subject, BUILD_END);
+               DESTROY_IF(subject);
+       }
+       else
+       {
+               cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, type,
+                                                                 BUILD_BLOB_ASN1_DER, chunk_create(buf, len),
+                                                                 BUILD_END);
        }
-
-       /* Parse certificate data blob */
-       cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, cert_info->type,
-                                                         BUILD_BLOB_ASN1_DER, chunk_create(buf, len),
-                                                         BUILD_END);
        if (cert)
        {
                if (*format & COMMAND_FORMAT_PEM)
@@ -117,16 +137,8 @@ CALLBACK(list_cb, void,
                }
                else
                {
-                       if (first)
-                       {
-                               printf("\nList of %ss:\n", cert_info->caption);
-                       }
-                       printf("\n");
-                       detailed = !(*format & COMMAND_FORMAT_SHORT);
-                       utc = *format & COMMAND_FORMAT_UTC;
-                       printer = certificate_printer_create(stdout, detailed, utc);
-                       printer->print(printer, cert, has_privkey);
-                       printer->destroy(printer);
+                       cert_printer->print_caption(cert_printer, type, flag);
+                       cert_printer->print(cert_printer, cert, has_privkey);
                }
                cert->destroy(cert);
        }
@@ -141,7 +153,8 @@ static int list_certs(vici_conn_t *conn)
        vici_req_t *req;
        vici_res_t *res;
        command_format_options_t format = COMMAND_FORMAT_NONE;
-       char *arg, *subject = NULL, *type = NULL;
+       char *arg, *subject = NULL, *type = NULL, *flag = NULL;
+       bool detailed = TRUE, utc = FALSE;
        int ret;
 
        while (TRUE)
@@ -156,6 +169,9 @@ static int list_certs(vici_conn_t *conn)
                        case 't':
                                type = arg;
                                continue;
+                       case 'f':
+                               flag = arg;
+                               continue;
                        case 'p':
                                format |= COMMAND_FORMAT_PEM;
                                continue;
@@ -166,10 +182,10 @@ static int list_certs(vici_conn_t *conn)
                                format |= COMMAND_FORMAT_RAW;
                                continue;
                        case 'S':
-                               format |= COMMAND_FORMAT_SHORT;
+                               detailed = FALSE;
                                continue;
                        case 'U':
-                               format |= COMMAND_FORMAT_UTC;
+                               utc = TRUE;
                                continue;
                        case EOF:
                                break;
@@ -186,22 +202,28 @@ static int list_certs(vici_conn_t *conn)
                return ret;
        }
        req = vici_begin("list-certs");
-       vici_add_version(req, VICI_VERSION);
 
        if (type)
        {
                vici_add_key_valuef(req, "type", "%s", type);
        }
+       if (flag)
+       {
+               vici_add_key_valuef(req, "flag", "%s", flag);
+       }
        if (subject)
        {
                vici_add_key_valuef(req, "subject", "%s", subject);
        }
+       cert_printer = certificate_printer_create(stdout, detailed, utc);
 
        res = vici_submit(req, conn);
        if (!res)
        {
                ret = errno;
                fprintf(stderr, "list-certs request failed: %s\n", strerror(errno));
+               cert_printer->destroy(cert_printer);
+               cert_printer = NULL;
                return ret;
        }
        if (format & COMMAND_FORMAT_RAW)
@@ -210,6 +232,9 @@ static int list_certs(vici_conn_t *conn)
                                  stdout);
        }
        vici_free_res(res);
+
+       cert_printer->destroy(cert_printer);
+       cert_printer = NULL;
        return 0;
 }
 
@@ -220,13 +245,14 @@ static void __attribute__ ((constructor))reg()
 {
        command_register((command_t) {
                list_certs, 'x', "list-certs", "list stored certificates",
-               {"[--subject <dn/san>] "
-                "[--type x509|x509ca|x509aa|x509ac|x509crl|x509ocsp|ocsp] "
-                "[--pem] [--raw|--pretty|--short|--utc]"},
+               {"[--subject <dn/san>] [--pem]",
+                "[--type x509|x509_ac|x509_crl|ocsp_response|pubkey]",
+                "[--flag none|ca|aa|ocsp|any] [--raw|--pretty|--short|--utc]"},
                {
                        {"help",                'h', 0, "show usage information"},
                        {"subject",             's', 1, "filter by certificate subject"},
                        {"type",                't', 1, "filter by certificate type"},
+                       {"flag",                'f', 1, "filter by X.509 certificate flag"},
                        {"pem",                 'p', 0, "print PEM encoding of certificate"},
                        {"raw",                 'r', 0, "dump raw response message"},
                        {"pretty",              'P', 0, "dump raw response message in pretty print"},