17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*99ebb4caSwyllys * Common Development and Distribution License (the "License"). 6*99ebb4caSwyllys * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*99ebb4caSwyllys * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* 297c478bd9Sstevel@tonic-gate * This file comprises the main driver for this tool. 307711facfSdinak * Upon parsing the command verbs from user input, it 317711facfSdinak * branches to the appropriate modules to perform the 327711facfSdinak * requested task. 337c478bd9Sstevel@tonic-gate */ 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate #include <stdio.h> 367c478bd9Sstevel@tonic-gate #include <string.h> 377c478bd9Sstevel@tonic-gate #include <ctype.h> 387c478bd9Sstevel@tonic-gate #include <malloc.h> 397c478bd9Sstevel@tonic-gate #include <libgen.h> 407c478bd9Sstevel@tonic-gate #include <errno.h> 417c478bd9Sstevel@tonic-gate #include <cryptoutil.h> 427c478bd9Sstevel@tonic-gate #include <security/cryptoki.h> 437c478bd9Sstevel@tonic-gate #include "common.h" 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate /* 467c478bd9Sstevel@tonic-gate * The verbcmd construct allows genericizing information about a verb so 477c478bd9Sstevel@tonic-gate * that it is easier to manipulate. Makes parsing code easier to read, 487c478bd9Sstevel@tonic-gate * fix, and extend with new verbs. 497c478bd9Sstevel@tonic-gate */ 507c478bd9Sstevel@tonic-gate typedef struct verbcmd_s { 517c478bd9Sstevel@tonic-gate char *verb; 527c478bd9Sstevel@tonic-gate int (*action)(int, char *[]); 537711facfSdinak int mode; 547711facfSdinak char *synopsis; 557c478bd9Sstevel@tonic-gate } verbcmd; 567c478bd9Sstevel@tonic-gate 577c478bd9Sstevel@tonic-gate /* External declarations for supported verb actions. */ 587c478bd9Sstevel@tonic-gate extern int pk_setpin(int argc, char *argv[]); 597711facfSdinak extern int pk_list(int argc, char *argv[]); 607711facfSdinak extern int pk_delete(int argc, char *argv[]); 617711facfSdinak extern int pk_import(int argc, char *argv[]); 627711facfSdinak extern int pk_export(int argc, char *argv[]); 637711facfSdinak extern int pk_tokens(int argc, char *argv[]); 64*99ebb4caSwyllys extern int pk_gencert(int argc, char *argv[]); 65*99ebb4caSwyllys extern int pk_gencsr(int argc, char *argv[]); 66*99ebb4caSwyllys extern int pk_download(int argc, char *argv[]); 67*99ebb4caSwyllys extern int pk_genkey(int argc, char *argv[]); 687711facfSdinak 697711facfSdinak /* Forward declarations for "built-in" verb actions. */ 707711facfSdinak static int pk_help(int argc, char *argv[]); 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* Command structure for verbs and their actions. Do NOT i18n/l10n. */ 737c478bd9Sstevel@tonic-gate static verbcmd cmds[] = { 747711facfSdinak { "tokens", pk_tokens, 0, "tokens" }, 7549e21299Sdinak { "setpin", pk_setpin, 0, 76*99ebb4caSwyllys "setpin [ keystore=pkcs11 ]\n\t\t" 77*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 78*99ebb4caSwyllys 79*99ebb4caSwyllys "setpin keystore=nss\n\t\t" 80*99ebb4caSwyllys "[ token=token ]\n\t\t" 81*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 82*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 83*99ebb4caSwyllys }, 8449e21299Sdinak { "list", pk_list, 0, 85*99ebb4caSwyllys 86*99ebb4caSwyllys "list [ token=token[:manuf[:serial]]]\n\t\t" 87*99ebb4caSwyllys "[ objtype=private|public|both ]\n\t\t" 88*99ebb4caSwyllys "[ label=label ]\n\t" 89*99ebb4caSwyllys 90*99ebb4caSwyllys "list objtype=cert[:[public | private | both ]]\n\t\t" 91*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 92*99ebb4caSwyllys "[ keystore=pkcs11 ]\n\t\t" 93*99ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 94*99ebb4caSwyllys "[ serial=serial number]\n\t\t" 95*99ebb4caSwyllys "[ label=cert-label ]\n\t\t" 96*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 97*99ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 98*99ebb4caSwyllys 99*99ebb4caSwyllys "list objtype=key[:[public | private | both ]]\n\t\t" 100*99ebb4caSwyllys "[ keystore=pkcs11 ]\n\t\t" 101*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 102*99ebb4caSwyllys "[ label=key-label ]\n\t\t" 103*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 104*99ebb4caSwyllys 105*99ebb4caSwyllys "list keystore=pkcs11 objtype=crl\n\t\t" 106*99ebb4caSwyllys "infile=crl-fn\n\t\t" 107*99ebb4caSwyllys "[ dir=directory-path ]\n\t" 108*99ebb4caSwyllys 109*99ebb4caSwyllys "list keystore=nss objtype=cert\n\t\t" 110*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 111*99ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 112*99ebb4caSwyllys "[ serial=serial number]\n\t\t" 113*99ebb4caSwyllys "[ nickname=cert-nickname ]\n\t\t" 114*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 115*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 116*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 117*99ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 118*99ebb4caSwyllys 119*99ebb4caSwyllys "list keystore=nss objtype=key\n\t\t" 120*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 121*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 122*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 123*99ebb4caSwyllys "[ nickname=key-nickname ]\n\t" 124*99ebb4caSwyllys 125*99ebb4caSwyllys "list keystore=file objtype=cert\n\t\t" 126*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 127*99ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 128*99ebb4caSwyllys "[ serial=serial number]\n\t\t" 129*99ebb4caSwyllys "[ infile=cert-fn ]\n\t\t" 130*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 131*99ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 132*99ebb4caSwyllys 133*99ebb4caSwyllys "list keystore=file objtype=key\n\t\t" 134*99ebb4caSwyllys "[ infile=key-fn ]\n\t\t" 135*99ebb4caSwyllys "[ dir=directory-path ]\n\t" 136*99ebb4caSwyllys 137*99ebb4caSwyllys "list keystore=file objtype=crl\n\t\t" 138*99ebb4caSwyllys "infile=crl-fn\n\t\t" 139*99ebb4caSwyllys "[ dir=directory-path ]\n\t" 140*99ebb4caSwyllys }, 141*99ebb4caSwyllys 1427711facfSdinak { "delete", pk_delete, 0, 143*99ebb4caSwyllys 144*99ebb4caSwyllys "delete [ token=token[:manuf[:serial]]]\n\t\t" 145*99ebb4caSwyllys "[ objtype=private|public|both ]\n\t\t" 146*99ebb4caSwyllys "[ label=object-label ]\n\t" 147*99ebb4caSwyllys 148*99ebb4caSwyllys "delete keystore=nss objtype=cert\n\t\t" 149*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 150*99ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 151*99ebb4caSwyllys "[ serial=serial number]\n\t\t" 152*99ebb4caSwyllys "[ nickname=cert-nickname ]\n\t\t" 153*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 154*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 155*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 156*99ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 157*99ebb4caSwyllys 158*99ebb4caSwyllys "delete keystore=nss objtype=key\n\t\t" 159*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 160*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 161*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 162*99ebb4caSwyllys "[ nickname=key-nickname ]\n\t\t" 163*99ebb4caSwyllys 164*99ebb4caSwyllys "delete keystore=nss objtype=crl\n\t\t" 165*99ebb4caSwyllys "[ nickname=issuer-nickname ]\n\t\t" 166*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 167*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 168*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 169*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 170*99ebb4caSwyllys 171*99ebb4caSwyllys "delete keystore=pkcs11 objtype=cert[:[public | private | both]]\n\t\t" 172*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 173*99ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 174*99ebb4caSwyllys "[ serial=serial number]\n\t\t" 175*99ebb4caSwyllys "[ label=cert-label ]\n\t\t" 176*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 177*99ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 178*99ebb4caSwyllys 179*99ebb4caSwyllys "delete keystore=pkcs11 objtype=key[:[public | private | both]]\n\t\t" 180*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 181*99ebb4caSwyllys "[ label=key-label ]\n\t\t" 182*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 183*99ebb4caSwyllys 184*99ebb4caSwyllys "delete keystore=pkcs11 objtype=crl\n\t\t" 185*99ebb4caSwyllys "infile=crl-fn\n\t\t" 186*99ebb4caSwyllys "[ dir=directory-path ]\n\t" 187*99ebb4caSwyllys 188*99ebb4caSwyllys "delete keystore=file objtype=cert\n\t\t" 189*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 190*99ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 191*99ebb4caSwyllys "[ serial=serial number]\n\t\t" 192*99ebb4caSwyllys "[ infile=cert-fn ]\n\t\t" 193*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 194*99ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 195*99ebb4caSwyllys 196*99ebb4caSwyllys "delete keystore=file objtype=key\n\t\t" 197*99ebb4caSwyllys "[ infile=key-fn ]\n\t\t" 198*99ebb4caSwyllys "[ dir=directory-path ]\n\t" 199*99ebb4caSwyllys 200*99ebb4caSwyllys "delete keystore=file objtype=crl\n\t\t" 201*99ebb4caSwyllys "infile=crl-fn\n\t\t" 202*99ebb4caSwyllys "[ dir=directory-path ]\n\t" 203*99ebb4caSwyllys }, 20449e21299Sdinak { "import", pk_import, 0, 205*99ebb4caSwyllys 206*99ebb4caSwyllys "import [token=token[:manuf[:serial]]]\n\t\t" 207*99ebb4caSwyllys "infile=input-fn\n\t" 208*99ebb4caSwyllys 209*99ebb4caSwyllys "import keystore=nss objtype=cert\n\t\t" 210*99ebb4caSwyllys "infile=input-fn\n\t\t" 211*99ebb4caSwyllys "nickname=cert-nickname\n\t\t" 212*99ebb4caSwyllys "[ trust=trust-value ]\n\t\t" 213*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 214*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 215*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 216*99ebb4caSwyllys 217*99ebb4caSwyllys "import keystore=nss objtype=crl\n\t\t" 218*99ebb4caSwyllys "infile=input-fn\n\t\t" 219*99ebb4caSwyllys "[ verifycrl=y|n ]\n\t\t" 220*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 221*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 222*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 223*99ebb4caSwyllys 224*99ebb4caSwyllys "import keystore=pkcs11\n\t\t" 225*99ebb4caSwyllys "infile=input-fn\n\t\t" 226*99ebb4caSwyllys "label=cert-label\n\t\t" 227*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 228*99ebb4caSwyllys 229*99ebb4caSwyllys "import keystore=pkcs11 objtype=crl\n\t\t" 230*99ebb4caSwyllys "infile=input-crl-fn\n\t\t" 231*99ebb4caSwyllys "outcrl=output-crl-fn\n\t\t" 232*99ebb4caSwyllys "outformat=pem|der\n\t\t" 233*99ebb4caSwyllys "[ dir=output-crl-directory-path ]\n\t" 234*99ebb4caSwyllys 235*99ebb4caSwyllys "import keystore=file\n\t\t" 236*99ebb4caSwyllys "infile=input-fn\n\t\t" 237*99ebb4caSwyllys "outkey=output-key-fn\n\t\t" 238*99ebb4caSwyllys "outcert=output-cert-fn\n\t\t" 239*99ebb4caSwyllys "[ dir=output-cert-dir-path ]\n\t\t" 240*99ebb4caSwyllys "[ keydir=output-key-dir-path ]\n\t\t" 241*99ebb4caSwyllys "[ outformat=pem|der|pkcs12 ]\n\t" 242*99ebb4caSwyllys 243*99ebb4caSwyllys "import keystore=file objtype=crl\n\t\t" 244*99ebb4caSwyllys "infile=input-crl-fn\n\t\t" 245*99ebb4caSwyllys "outcrl=output-crl-fn\n\t\t" 246*99ebb4caSwyllys "outformat=pem|der\n\t\t" 247*99ebb4caSwyllys "[ dir=output-crl-directory-path ]\n\t" 248*99ebb4caSwyllys }, 249*99ebb4caSwyllys 25049e21299Sdinak { "export", pk_export, 0, 251*99ebb4caSwyllys 252*99ebb4caSwyllys "export [token=token[:manuf[:serial]]]\n\t\t" 253*99ebb4caSwyllys "outfile=output-fn\n\t" 254*99ebb4caSwyllys 255*99ebb4caSwyllys "export keystore=nss\n\t\t" 256*99ebb4caSwyllys "outfile=output-fn\n\t\t" 257*99ebb4caSwyllys "[ objtype=cert|key ]\n\t\t" 258*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 259*99ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 260*99ebb4caSwyllys "[ serial=serial number]\n\t\t" 261*99ebb4caSwyllys "[ nickname=cert-nickname]\n\t\t" 262*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 263*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 264*99ebb4caSwyllys "[ prefix=DBPrefix ]\n\t\t" 265*99ebb4caSwyllys "[ outformat=pem|der|pkcs12 ]\n\t" 266*99ebb4caSwyllys 267*99ebb4caSwyllys "export keystore=pkcs11\n\t\t" 268*99ebb4caSwyllys "outfile=output-fn\n\t\t" 269*99ebb4caSwyllys "[ label=cert-label]\n\t\t" 270*99ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 271*99ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 272*99ebb4caSwyllys "[ serial=serial number]\n\t\t" 273*99ebb4caSwyllys "[ outformat=pem|der|pkcs12]\n\t\t" 274*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 275*99ebb4caSwyllys 276*99ebb4caSwyllys "export keystore=file\n\t\t" 277*99ebb4caSwyllys "certfile=cert-input-fn\n\t\t" 278*99ebb4caSwyllys "keyfile=key-input-fn\n\t\t" 279*99ebb4caSwyllys "outfile=output-pkcs12-fn\n\t\t" 280*99ebb4caSwyllys "[ dir=directory-path ]\n\t" 281*99ebb4caSwyllys }, 282*99ebb4caSwyllys 283*99ebb4caSwyllys { "gencert", pk_gencert, 0, 284*99ebb4caSwyllys "gencert [-i] keystore=nss\n\t\t" 285*99ebb4caSwyllys "label=cert-nickname\n\t\t" 286*99ebb4caSwyllys "serial=serial number hex string]\n\t\t" 287*99ebb4caSwyllys "subject=subject-DN\n\t\t" 288*99ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 289*99ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 290*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 291*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 292*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 293*99ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 294*99ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 295*99ebb4caSwyllys "[ trust=trust-value ]\n\t\t" 296*99ebb4caSwyllys "[ lifetime=number-hour|number-day|number-year ]\n\t" 297*99ebb4caSwyllys 298*99ebb4caSwyllys "gencert [-i] [ keystore=pkcs11 ]\n\t\t" 299*99ebb4caSwyllys "label=key/cert-label\n\t\t" 300*99ebb4caSwyllys "subject=subject-DN\n\t\t" 301*99ebb4caSwyllys "serial=serial number hex string\n\t\t" 302*99ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 303*99ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 304*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 305*99ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 306*99ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 307*99ebb4caSwyllys "[ lifetime=number-hour|number-day|number-year ]\n\t" 308*99ebb4caSwyllys 309*99ebb4caSwyllys "gencert [-i] keystore=file\n\t\t" 310*99ebb4caSwyllys "outcert=cert_filename\n\t\t" 311*99ebb4caSwyllys "outkey=key_filename\n\t\t" 312*99ebb4caSwyllys "subject=subject-DN\n\t\t" 313*99ebb4caSwyllys "serial=serial number hex string\n\t\t" 314*99ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 315*99ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 316*99ebb4caSwyllys "[ format=der|pem ]\n\t\t" 317*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 318*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 319*99ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 320*99ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 321*99ebb4caSwyllys "[ lifetime=number-hour|number-day|number-year ]\n\t" 322*99ebb4caSwyllys }, 323*99ebb4caSwyllys { "gencsr", pk_gencsr, 0, 324*99ebb4caSwyllys "gencsr [-i] keystore=nss \n\t\t" 325*99ebb4caSwyllys "nickname=cert-nickname\n\t\t" 326*99ebb4caSwyllys "outcsr=csr-fn\n\t\t" 327*99ebb4caSwyllys "subject=subject-DN\n\t\t" 328*99ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 329*99ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 330*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 331*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 332*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 333*99ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 334*99ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 335*99ebb4caSwyllys "[ format=pem|der]\n\t" 336*99ebb4caSwyllys "gencsr [-i] [ keystore=pkcs11 ]\n\t\t" 337*99ebb4caSwyllys "label=key-label\n\t\t" 338*99ebb4caSwyllys "outcsr=csr-fn\n\t\t" 339*99ebb4caSwyllys "subject=subject-DN\n\t\t" 340*99ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 341*99ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 342*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 343*99ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 344*99ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 345*99ebb4caSwyllys "[ format=pem|der]\n\t" 346*99ebb4caSwyllys "gencsr [-i] keystore=file\n\t\t" 347*99ebb4caSwyllys "outcsr=csr-fn\n\t\t" 348*99ebb4caSwyllys "outkey=key-fn\n\t\t" 349*99ebb4caSwyllys "subject=subject-DN\n\t\t" 350*99ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 351*99ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 352*99ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 353*99ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 354*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 355*99ebb4caSwyllys "[ format=pem|der]\n\t" 356*99ebb4caSwyllys }, 357*99ebb4caSwyllys 358*99ebb4caSwyllys { "download", pk_download, 0, 359*99ebb4caSwyllys "download url=url_str\n\t\t" 360*99ebb4caSwyllys "[ objtype=crl|cert ]\n\t\t" 361*99ebb4caSwyllys "[ http_proxy=proxy_str ]\n\t\t" 362*99ebb4caSwyllys "[ outfile = outfile ]\n\t\t" 363*99ebb4caSwyllys }, 364*99ebb4caSwyllys 365*99ebb4caSwyllys { "genkey", pk_genkey, 0, 366*99ebb4caSwyllys "genkey [ keystore=pkcs11 ]\n\t\t" 367*99ebb4caSwyllys "label=key-label\n\t\t" 368*99ebb4caSwyllys "[ keytype=aes|arcfour|des|3des ]\n\t\t" 369*99ebb4caSwyllys "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" 370*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 371*99ebb4caSwyllys "[ sensitive=y|n ]\n\t\t" 372*99ebb4caSwyllys "[ extractable=y|n ]\n\t\t" 373*99ebb4caSwyllys "[ print=y|n ]\n\t" 374*99ebb4caSwyllys 375*99ebb4caSwyllys "genkey keystore=nss\n\t\t" 376*99ebb4caSwyllys "label=key-label\n\t\t" 377*99ebb4caSwyllys "[ keytype=aes|arcfour|des|3des ]\n\t\t" 378*99ebb4caSwyllys "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" 379*99ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 380*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 381*99ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 382*99ebb4caSwyllys 383*99ebb4caSwyllys "genkey keystore=file\n\t\t" 384*99ebb4caSwyllys "outkey=key-fn\n\t\t" 385*99ebb4caSwyllys "[ keytype=aes|arcfour|des|3des ]\n\t\t" 386*99ebb4caSwyllys "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" 387*99ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 388*99ebb4caSwyllys "[ print=y|n ]\n\t" 389*99ebb4caSwyllys }, 390*99ebb4caSwyllys 39149e21299Sdinak { "-?", pk_help, 0, "help\t(help and usage)" }, 392*99ebb4caSwyllys { "-f", pk_help, 0, "-f option_file" } 3937c478bd9Sstevel@tonic-gate }; 3947c478bd9Sstevel@tonic-gate static int num_cmds = sizeof (cmds) / sizeof (verbcmd); 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate static char *prog; 397*99ebb4caSwyllys static void usage(int); 3987c478bd9Sstevel@tonic-gate 3997c478bd9Sstevel@tonic-gate /* 4007c478bd9Sstevel@tonic-gate * Usage information. This function must be updated when new verbs or 4017c478bd9Sstevel@tonic-gate * options are added. 4027c478bd9Sstevel@tonic-gate */ 4037c478bd9Sstevel@tonic-gate static void 404*99ebb4caSwyllys usage(int idx) 4057c478bd9Sstevel@tonic-gate { 4067711facfSdinak int i; 4077711facfSdinak 4087711facfSdinak /* Display this block only in command-line mode. */ 4097711facfSdinak (void) fprintf(stdout, gettext("Usage:\n")); 4107711facfSdinak (void) fprintf(stdout, gettext("\t%s -?\t(help and usage)\n"), prog); 411*99ebb4caSwyllys (void) fprintf(stdout, gettext("\t%s -f option_file\n"), prog); 4127711facfSdinak (void) fprintf(stdout, gettext("\t%s subcommand [options...]\n"), prog); 4137711facfSdinak (void) fprintf(stdout, gettext("where subcommands may be:\n")); 4147711facfSdinak 4157711facfSdinak /* Display only those verbs that match the current tool mode. */ 416*99ebb4caSwyllys if (idx == -1) { 4177711facfSdinak for (i = 0; i < num_cmds; i++) { 4187711facfSdinak /* Do NOT i18n/l10n. */ 4197711facfSdinak (void) fprintf(stdout, "\t%s\n", cmds[i].synopsis); 4207711facfSdinak } 421*99ebb4caSwyllys } else { 422*99ebb4caSwyllys (void) fprintf(stdout, "\t%s\n", cmds[idx].synopsis); 423*99ebb4caSwyllys } 4247711facfSdinak } 4257711facfSdinak 4267711facfSdinak /* 4277711facfSdinak * Provide help, in the form of displaying the usage. 4287711facfSdinak */ 4297711facfSdinak static int 4307711facfSdinak pk_help(int argc, char *argv[]) 4317711facfSdinak /* ARGSUSED */ 4327711facfSdinak { 433*99ebb4caSwyllys usage(-1); 434*99ebb4caSwyllys return (0); 435*99ebb4caSwyllys } 4367711facfSdinak 437*99ebb4caSwyllys /* 438*99ebb4caSwyllys * Process arguments from the argfile and create a new 439*99ebb4caSwyllys * argv/argc list to be processed later. 440*99ebb4caSwyllys */ 441*99ebb4caSwyllys static int 442*99ebb4caSwyllys process_arg_file(char *argfile, char ***argv, int *argc) 443*99ebb4caSwyllys { 444*99ebb4caSwyllys FILE *fp; 445*99ebb4caSwyllys char argline[2 * BUFSIZ]; /* 2048 bytes should be plenty */ 446*99ebb4caSwyllys char *p; 447*99ebb4caSwyllys int nargs = 0; 448*99ebb4caSwyllys 449*99ebb4caSwyllys if ((fp = fopen(argfile, "rF")) == NULL) { 450*99ebb4caSwyllys (void) fprintf(stderr, 451*99ebb4caSwyllys gettext("Cannot read argfile %s: %s\n"), 452*99ebb4caSwyllys argfile, strerror(errno)); 453*99ebb4caSwyllys return (errno); 454*99ebb4caSwyllys } 455*99ebb4caSwyllys 456*99ebb4caSwyllys while (fgets(argline, sizeof (argline), fp) != NULL) { 457*99ebb4caSwyllys int j; 458*99ebb4caSwyllys /* remove trailing whitespace */ 459*99ebb4caSwyllys j = strlen(argline) - 1; 460*99ebb4caSwyllys while (j >= 0 && isspace(argline[j])) { 461*99ebb4caSwyllys argline[j] = 0; 462*99ebb4caSwyllys j--; 463*99ebb4caSwyllys } 464*99ebb4caSwyllys /* If it was a blank line, get the next one. */ 465*99ebb4caSwyllys if (!strlen(argline)) 466*99ebb4caSwyllys continue; 467*99ebb4caSwyllys 468*99ebb4caSwyllys (*argv) = realloc((*argv), 469*99ebb4caSwyllys (nargs + 1) * sizeof (char *)); 470*99ebb4caSwyllys if ((*argv) == NULL) { 471*99ebb4caSwyllys perror("memory error"); 472*99ebb4caSwyllys (void) fclose(fp); 473*99ebb4caSwyllys return (errno); 474*99ebb4caSwyllys } 475*99ebb4caSwyllys p = (char *)strdup(argline); 476*99ebb4caSwyllys if (p == NULL) { 477*99ebb4caSwyllys perror("memory error"); 478*99ebb4caSwyllys (void) fclose(fp); 479*99ebb4caSwyllys return (errno); 480*99ebb4caSwyllys } 481*99ebb4caSwyllys (*argv)[nargs] = p; 482*99ebb4caSwyllys nargs++; 483*99ebb4caSwyllys } 484*99ebb4caSwyllys *argc = nargs; 485*99ebb4caSwyllys (void) fclose(fp); 4867711facfSdinak return (0); 4877c478bd9Sstevel@tonic-gate } 4887c478bd9Sstevel@tonic-gate 4897c478bd9Sstevel@tonic-gate /* 4907c478bd9Sstevel@tonic-gate * MAIN() -- where all the action is 4917c478bd9Sstevel@tonic-gate */ 4927c478bd9Sstevel@tonic-gate int 4937c478bd9Sstevel@tonic-gate main(int argc, char *argv[], char *envp[]) 4947c478bd9Sstevel@tonic-gate /* ARGSUSED2 */ 4957c478bd9Sstevel@tonic-gate { 4967c478bd9Sstevel@tonic-gate int i, found = -1; 4977c478bd9Sstevel@tonic-gate int rv; 4987c478bd9Sstevel@tonic-gate int pk_argc = 0; 4997c478bd9Sstevel@tonic-gate char **pk_argv = NULL; 5007711facfSdinak int save_errno = 0; 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /* Set up for i18n/l10n. */ 5037c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 5047c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D. */ 5057c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't. */ 5067c478bd9Sstevel@tonic-gate #endif 5077c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate /* Get program base name and move pointer over 0th arg. */ 5107c478bd9Sstevel@tonic-gate prog = basename(argv[0]); 5117c478bd9Sstevel@tonic-gate argv++, argc--; 5127c478bd9Sstevel@tonic-gate 5137c478bd9Sstevel@tonic-gate /* Set up for debug and error output. */ 5147c478bd9Sstevel@tonic-gate if (argc == 0) { 515*99ebb4caSwyllys usage(-1); 5167c478bd9Sstevel@tonic-gate return (1); 5177c478bd9Sstevel@tonic-gate } 5187c478bd9Sstevel@tonic-gate 5197711facfSdinak /* Check for help options. For CLIP-compliance. */ 520*99ebb4caSwyllys if (strcmp(argv[0], "-?") == 0) { 5217711facfSdinak return (pk_help(argc, argv)); 522*99ebb4caSwyllys } else if (strcmp(argv[0], "-f") == 0 && argc == 2) { 523*99ebb4caSwyllys rv = process_arg_file(argv[1], &pk_argv, &pk_argc); 524*99ebb4caSwyllys if (rv) 525*99ebb4caSwyllys return (rv); 526*99ebb4caSwyllys } else if (argc >= 1 && argv[0][0] == '-') { 527*99ebb4caSwyllys usage(-1); 5287711facfSdinak return (1); 5297711facfSdinak } 5307711facfSdinak 5317711facfSdinak /* Always turns off Metaslot so that we can see softtoken. */ 5327c478bd9Sstevel@tonic-gate if (setenv("METASLOT_ENABLED", "false", 1) < 0) { 5337711facfSdinak save_errno = errno; 5347c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 5357711facfSdinak gettext("Disabling Metaslot failed (%s)."), 5367711facfSdinak strerror(save_errno)); 5377c478bd9Sstevel@tonic-gate return (1); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate /* Begin parsing command line. */ 541*99ebb4caSwyllys if (pk_argc == 0 && pk_argv == NULL) { 5427c478bd9Sstevel@tonic-gate pk_argc = argc; 5437c478bd9Sstevel@tonic-gate pk_argv = argv; 544*99ebb4caSwyllys } 5457c478bd9Sstevel@tonic-gate 5467711facfSdinak /* Check for valid verb (or an abbreviation of it). */ 5477c478bd9Sstevel@tonic-gate found = -1; 5487c478bd9Sstevel@tonic-gate for (i = 0; i < num_cmds; i++) { 5497c478bd9Sstevel@tonic-gate if (strcmp(cmds[i].verb, pk_argv[0]) == 0) { 5507c478bd9Sstevel@tonic-gate if (found < 0) { 5517c478bd9Sstevel@tonic-gate found = i; 5527c478bd9Sstevel@tonic-gate break; 5537c478bd9Sstevel@tonic-gate } 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate /* Stop here if no valid verb found. */ 5577c478bd9Sstevel@tonic-gate if (found < 0) { 5587711facfSdinak cryptoerror(LOG_STDERR, gettext("Invalid verb: %s"), 5597711facfSdinak pk_argv[0]); 5607c478bd9Sstevel@tonic-gate return (1); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate /* Get to work! */ 5647c478bd9Sstevel@tonic-gate rv = (*cmds[found].action)(pk_argc, pk_argv); 5657c478bd9Sstevel@tonic-gate switch (rv) { 5667c478bd9Sstevel@tonic-gate case PK_ERR_NONE: 5677c478bd9Sstevel@tonic-gate break; /* Command succeeded, do nothing. */ 5687c478bd9Sstevel@tonic-gate case PK_ERR_USAGE: 569*99ebb4caSwyllys usage(found); 5707c478bd9Sstevel@tonic-gate break; 5717c478bd9Sstevel@tonic-gate case PK_ERR_QUIT: 5727c478bd9Sstevel@tonic-gate exit(0); 5737c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5747711facfSdinak case PK_ERR_PK11: 5757711facfSdinak case PK_ERR_SYSTEM: 5767711facfSdinak case PK_ERR_OPENSSL: 577*99ebb4caSwyllys case PK_ERR_NSS: 5787c478bd9Sstevel@tonic-gate default: 5797c478bd9Sstevel@tonic-gate break; 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate return (rv); 5827c478bd9Sstevel@tonic-gate } 583