1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  *
  21  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
  22  */
  23 
  24 /*
  25  * Copyright (c) 2018, Joyent, Inc.
  26  */
  27 
  28 #include <stdio.h>
  29 #include <strings.h>
  30 #include <ctype.h>
  31 #include <libgen.h>
  32 #include <libintl.h>
  33 #include <locale.h>
  34 
  35 #include <kmfapiP.h>
  36 
  37 #include "util.h"
  38 
  39 /*
  40  * The verbcmd construct allows genericizing information about a verb so
  41  * that it is easier to manipulate.  Makes parsing code easier to read,
  42  * fix, and extend with new verbs.
  43  */
  44 typedef struct verbcmd_s {
  45         char            *verb;
  46         int             (*action)(int, char *[]);
  47         char            *synopsis;
  48 } verbcmd;
  49 
  50 int     kc_list(int argc, char *argv[]);
  51 int     kc_delete(int argc, char *argv[]);
  52 int     kc_create(int argc, char *argv[]);
  53 int     kc_modify(int argc, char *argv[]);
  54 int     kc_export(int argc, char *argv[]);
  55 int     kc_import(int argc, char *argv[]);
  56 int     kc_install(int argc, char *argv[]);
  57 int     kc_uninstall(int argc, char *argv[]);
  58 
  59 static int      kc_help();
  60 
  61 static verbcmd cmds[] = {
  62         { "list",       kc_list,
  63                 "list [dbfile=dbfile] [policy=policyname]\n"
  64                 "\tlist plugin" },
  65         { "delete",     kc_delete, "delete [dbfile=dbfile] "
  66                 "policy=policyname" },
  67         { "create",     kc_create,
  68                 "create [dbfile=dbfile] policy=policyname\n"
  69                 "\t\t[ignore-date=true|false]\n"
  70                 "\t\t[ignore-unknown-eku=true|false]\n"
  71                 "\t\t[ignore-trust-anchor=true|false]\n"
  72                 "\t\t[validity-adjusttime=adjusttime]\n"
  73                 "\t\t[ta-name=trust anchor subject DN]\n"
  74                 "\t\t[ta-serial=trust anchor serial number]\n"
  75                 "\t\t[ocsp-responder=URL]\n"
  76                 "\t\t[ocsp-proxy=URL]\n"
  77                 "\t\t[ocsp-use-cert-responder=true|false]\n"
  78                 "\t\t[ocsp-response-lifetime=timelimit]\n"
  79                 "\t\t[ocsp-ignore-response-sign=true|false]\n"
  80                 "\t\t[ocsp-responder-cert-name=Issuer DN]\n"
  81                 "\t\t[ocsp-responder-cert-serial=serial number]\n"
  82                 "\t\t[crl-basefilename=basefilename]\n"
  83                 "\t\t[crl-directory=directory]\n"
  84                 "\t\t[crl-get-crl-uri=true|false]\n"
  85                 "\t\t[crl-proxy=URL]\n"
  86                 "\t\t[crl-ignore-crl-sign=true|false]\n"
  87                 "\t\t[crl-ignore-crl-date=true|false]\n"
  88                 "\t\t[keyusage=digitalSignature|nonRepudiation\n\t"
  89                 "\t\t|keyEncipherment | dataEncipherment |\n\t"
  90                 "\t\tkeyAgreement |keyCertSign |\n\t"
  91                 "\t\tcRLSign | encipherOnly | decipherOnly],[...]\n"
  92                 "\t\t[ekunames=serverAuth | clientAuth |\n\t"
  93                 "\t\tcodeSigning | emailProtection |\n\t"
  94                 "\t\tipsecEndSystem | ipsecTunnel |\n\t"
  95                 "\t\tipsecUser | timeStamping |\n\t"
  96                 "\t\tOCSPSigning],[...]\n"
  97                 "\t\t[ekuoids=OID,OID,OID...]\n"
  98                 "\t\t[mapper-name=name of mapper library]\n"
  99                 "\t\t[mapper-directory=dir where mapper library resides]\n"
 100                 "\t\t[mapper-path=full pathname of mapper library]\n"
 101                 "\t\t[mapper-options=mapper options]\n"},
 102         { "modify",     kc_modify,
 103                 "modify [dbfile=dbfile] policy=policyname\n"
 104                 "\t\t[ignore-date=true|false]\n"
 105                 "\t\t[ignore-unknown-eku=true|false]\n"
 106                 "\t\t[ignore-trust-anchor=true|false]\n"
 107                 "\t\t[validity-adjusttime=adjusttime]\n"
 108                 "\t\t[ta-name=trust anchor subject DN | search]\n"
 109                 "\t\t[ta-serial=trust anchor serial number]\n"
 110                 "\t\t[ocsp-responder=URL]\n"
 111                 "\t\t[ocsp-proxy=URL]\n"
 112                 "\t\t[ocsp-use-cert-responder=true|false]\n"
 113                 "\t\t[ocsp-response-lifetime=timelimit]\n"
 114                 "\t\t[ocsp-ignore-response-sign=true|false]\n"
 115                 "\t\t[ocsp-responder-cert-name=Issuer DN]\n"
 116                 "\t\t[ocsp-responder-cert-serial=serial number]\n"
 117                 "\t\t[ocsp-none=true|false]\n"
 118                 "\t\t[crl-basefilename=basefilename]\n"
 119                 "\t\t[crl-directory=directory]\n"
 120                 "\t\t[crl-get-crl-uri=true|false]\n"
 121                 "\t\t[crl-proxy=URL]\n"
 122                 "\t\t[crl-ignore-crl-sign=true|false]\n"
 123                 "\t\t[crl-ignore-crl-date=true|false]\n"
 124                 "\t\t[crl-none=true|false]\n"
 125                 "\t\t[keyusage=digitalSignature|nonRepudiation\n\t"
 126                 "\t\t|keyEncipherment | dataEncipherment |\n\t"
 127                 "\t\tkeyAgreement |keyCertSign |\n\t"
 128                 "\t\tcRLSign | encipherOnly | decipherOnly],[...]\n"
 129                 "\t\t[keyusage-none=true|false]\n"
 130                 "\t\t[ekunames=serverAuth | clientAuth |\n\t"
 131                 "\t\tcodeSigning | emailProtection |\n\t"
 132                 "\t\tipsecEndSystem | ipsecTunnel |\n\t"
 133                 "\t\tipsecUser | timeStamping |\n\t"
 134                 "\t\tOCSPSigning],[...]\n"
 135                 "\t\t[ekuoids=OID,OID,OID...]\n"
 136                 "\t\t[eku-none=true|false]\n\n"
 137                 "\t\t[mapper-name=name of mapper library]\n"
 138                 "\t\t[mapper-directory=dir where mapper library resides]\n"
 139                 "\t\t[mapper-path=full pathname of mapper library]\n"
 140                 "\t\t[mapper-options=mapper options]\n"
 141                 "\tmodify plugin keystore=keystorename option=optionstring\n"},
 142 
 143         { "import",     kc_import, "import [dbfile=dbfile] policy=policyname "
 144                 "infile=inputdbfile\n" },
 145         { "export",     kc_export, "export [dbfile=dbfile] policy=policyname "
 146                 "outfile=newdbfile\n" },
 147         { "install",    kc_install, "install keystore=keystorename "
 148                 "modulepath=path [option=optionstring]\n"},
 149         { "uninstall",  kc_uninstall, "uninstall keystore=keystorename\n"},
 150         { "-?",         kc_help,        "help"},
 151         { "help",       kc_help,        ""}
 152 };
 153 
 154 static int num_cmds = sizeof (cmds) / sizeof (verbcmd);
 155 static char *prog;
 156 
 157 static void
 158 usage(void)
 159 {
 160         int i;
 161 
 162         /* Display this block only in command-line mode. */
 163         (void) fprintf(stdout, gettext("Usage:\n"));
 164         (void) fprintf(stdout, gettext("\t%s -?\t(help and usage)\n"), prog);
 165         (void) fprintf(stdout, gettext("\t%s subcommand [options...]\n"), prog);
 166         (void) fprintf(stdout, gettext("where subcommands may be:\n"));
 167 
 168         /* Display only those verbs that match the current tool mode. */
 169         for (i = 0; i < num_cmds; i++) {
 170                 /* Do NOT i18n/l10n. */
 171                 (void) fprintf(stdout, "\t%s\n", cmds[i].synopsis);
 172         }
 173 }
 174 
 175 static int
 176 kc_help()
 177 {
 178         usage();
 179         return (0);
 180 }
 181 
 182 int
 183 main(int argc, char *argv[])
 184 {
 185         int ret;
 186         int found;
 187         int i;
 188 
 189         (void) setlocale(LC_ALL, "");
 190 #if !defined(TEXT_DOMAIN)               /* Should be defined by cc -D. */
 191 #define TEXT_DOMAIN     "SYS_TEST"      /* Use this only if it isn't. */
 192 #endif
 193         (void) textdomain(TEXT_DOMAIN);
 194 
 195         prog = basename(argv[0]);
 196         argv++;
 197         argc--;
 198 
 199         if (argc == 0) {
 200                 usage();
 201                 exit(1);
 202         }
 203 
 204         if (argc == 1 && argv[0][0] == '-') {
 205                 switch (argv[0][1]) {
 206                         case '?':
 207                                 return (kc_help());
 208                         default:
 209                                 usage();
 210                                 exit(1);
 211                 }
 212         }
 213 
 214         found = -1;
 215         for (i = 0; i < num_cmds; i++) {
 216                 if (strcmp(cmds[i].verb, argv[0]) == 0) {
 217                         found = i;
 218                         break;
 219                 }
 220         }
 221 
 222         if (found < 0) {
 223                 (void) fprintf(stderr, gettext("Invalid command: %s\n"),
 224                     argv[0]);
 225                 exit(1);
 226         }
 227 
 228         /*
 229          * Note the action functions can return values from
 230          * the key management framework, and those values can conflict
 231          * with the utility error codes.
 232          */
 233         ret = (*cmds[found].action)(argc, argv);
 234 
 235         switch (ret) {
 236                 case KC_OK:
 237                         break;
 238                 case KC_ERR_USAGE:
 239                         break;
 240                 case KC_ERR_LOADDB:
 241                         (void) fprintf(stderr,
 242                             gettext("Error loading database\n"));
 243                         break;
 244                 case KC_ERR_FIND_POLICY:
 245                         break;
 246                 case KC_ERR_DELETE_POLICY:
 247                         (void) fprintf(stderr, gettext("Error deleting policy "
 248                             "from database.\n"));
 249                         break;
 250                 case KC_ERR_ADD_POLICY:
 251                         break;
 252                 case KC_ERR_VERIFY_POLICY:
 253                         break;
 254                 case KC_ERR_INCOMPLETE_POLICY:
 255                         break;
 256                 case KC_ERR_MEMORY:
 257                         (void) fprintf(stderr, gettext("Out of memory.\n"));
 258                         break;
 259                 case KC_ERR_ACCESS:
 260                         break;
 261                 case KC_ERR_INSTALL:
 262                         break;
 263                 case KC_ERR_UNINSTALL:
 264                         break;
 265                 default:
 266                         (void) fprintf(stderr, gettext("%s operation failed. "
 267                             "error 0x%02x\n"), cmds[found].verb, ret);
 268                         break;
 269         }
 270 
 271         return (ret);
 272 }