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 }