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 599ebb4caSwyllys * Common Development and Distribution License (the "License"). 699ebb4caSwyllys * 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*985be8f1Swyllys * Copyright 2007 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; 54*985be8f1Swyllys char *summary; 557711facfSdinak char *synopsis; 567c478bd9Sstevel@tonic-gate } verbcmd; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /* External declarations for supported verb actions. */ 597c478bd9Sstevel@tonic-gate extern int pk_setpin(int argc, char *argv[]); 607711facfSdinak extern int pk_list(int argc, char *argv[]); 617711facfSdinak extern int pk_delete(int argc, char *argv[]); 627711facfSdinak extern int pk_import(int argc, char *argv[]); 637711facfSdinak extern int pk_export(int argc, char *argv[]); 647711facfSdinak extern int pk_tokens(int argc, char *argv[]); 6599ebb4caSwyllys extern int pk_gencert(int argc, char *argv[]); 6699ebb4caSwyllys extern int pk_gencsr(int argc, char *argv[]); 6799ebb4caSwyllys extern int pk_download(int argc, char *argv[]); 6899ebb4caSwyllys extern int pk_genkey(int argc, char *argv[]); 697711facfSdinak 707711facfSdinak /* Forward declarations for "built-in" verb actions. */ 717711facfSdinak static int pk_help(int argc, char *argv[]); 727c478bd9Sstevel@tonic-gate 737c478bd9Sstevel@tonic-gate /* Command structure for verbs and their actions. Do NOT i18n/l10n. */ 747c478bd9Sstevel@tonic-gate static verbcmd cmds[] = { 75*985be8f1Swyllys { "tokens", pk_tokens, 0, 76*985be8f1Swyllys "lists all visible PKCS#11 tokens", "tokens" }, 7749e21299Sdinak { "setpin", pk_setpin, 0, 78*985be8f1Swyllys "changes user authentication passphrase for keystore access", 7999ebb4caSwyllys "setpin [ keystore=pkcs11 ]\n\t\t" 8099ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 8199ebb4caSwyllys 8299ebb4caSwyllys "setpin keystore=nss\n\t\t" 8399ebb4caSwyllys "[ token=token ]\n\t\t" 8499ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 8599ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 8699ebb4caSwyllys }, 8749e21299Sdinak { "list", pk_list, 0, 88*985be8f1Swyllys "lists a summary of objects in the keystore", 8999ebb4caSwyllys "list [ token=token[:manuf[:serial]]]\n\t\t" 9099ebb4caSwyllys "[ objtype=private|public|both ]\n\t\t" 9199ebb4caSwyllys "[ label=label ]\n\t" 9299ebb4caSwyllys 9399ebb4caSwyllys "list objtype=cert[:[public | private | both ]]\n\t\t" 9499ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 9599ebb4caSwyllys "[ keystore=pkcs11 ]\n\t\t" 9699ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 9799ebb4caSwyllys "[ serial=serial number]\n\t\t" 9899ebb4caSwyllys "[ label=cert-label ]\n\t\t" 9999ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 10099ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 10199ebb4caSwyllys 10299ebb4caSwyllys "list objtype=key[:[public | private | both ]]\n\t\t" 10399ebb4caSwyllys "[ keystore=pkcs11 ]\n\t\t" 10499ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 10599ebb4caSwyllys "[ label=key-label ]\n\t\t" 10699ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 10799ebb4caSwyllys 10899ebb4caSwyllys "list keystore=pkcs11 objtype=crl\n\t\t" 10999ebb4caSwyllys "infile=crl-fn\n\t\t" 11099ebb4caSwyllys "[ dir=directory-path ]\n\t" 11199ebb4caSwyllys 11299ebb4caSwyllys "list keystore=nss objtype=cert\n\t\t" 11399ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 11499ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 11599ebb4caSwyllys "[ serial=serial number]\n\t\t" 11699ebb4caSwyllys "[ nickname=cert-nickname ]\n\t\t" 11799ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 11899ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 11999ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 12099ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 12199ebb4caSwyllys 12299ebb4caSwyllys "list keystore=nss objtype=key\n\t\t" 12399ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 12499ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 12599ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 12699ebb4caSwyllys "[ nickname=key-nickname ]\n\t" 12799ebb4caSwyllys 12899ebb4caSwyllys "list keystore=file objtype=cert\n\t\t" 12999ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 13099ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 13199ebb4caSwyllys "[ serial=serial number]\n\t\t" 13299ebb4caSwyllys "[ infile=cert-fn ]\n\t\t" 13399ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 13499ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 13599ebb4caSwyllys 13699ebb4caSwyllys "list keystore=file objtype=key\n\t\t" 13799ebb4caSwyllys "[ infile=key-fn ]\n\t\t" 13899ebb4caSwyllys "[ dir=directory-path ]\n\t" 13999ebb4caSwyllys 14099ebb4caSwyllys "list keystore=file objtype=crl\n\t\t" 14199ebb4caSwyllys "infile=crl-fn\n\t\t" 14299ebb4caSwyllys "[ dir=directory-path ]\n\t" 14399ebb4caSwyllys }, 14499ebb4caSwyllys 1457711facfSdinak { "delete", pk_delete, 0, 146*985be8f1Swyllys "deletes objects in the keystore", 14799ebb4caSwyllys 14899ebb4caSwyllys "delete [ token=token[:manuf[:serial]]]\n\t\t" 14999ebb4caSwyllys "[ objtype=private|public|both ]\n\t\t" 15099ebb4caSwyllys "[ label=object-label ]\n\t" 15199ebb4caSwyllys 15299ebb4caSwyllys "delete keystore=nss objtype=cert\n\t\t" 15399ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 15499ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 15599ebb4caSwyllys "[ serial=serial number]\n\t\t" 15699ebb4caSwyllys "[ nickname=cert-nickname ]\n\t\t" 15799ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 15899ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 15999ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 16099ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 16199ebb4caSwyllys 16299ebb4caSwyllys "delete keystore=nss objtype=key\n\t\t" 16399ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 16499ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 16599ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 16699ebb4caSwyllys "[ nickname=key-nickname ]\n\t\t" 16799ebb4caSwyllys 16899ebb4caSwyllys "delete keystore=nss objtype=crl\n\t\t" 16999ebb4caSwyllys "[ nickname=issuer-nickname ]\n\t\t" 17099ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 17199ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 17299ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 17399ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 17499ebb4caSwyllys 17599ebb4caSwyllys "delete keystore=pkcs11 objtype=cert[:[public | private | both]]\n\t\t" 17699ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 17799ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 17899ebb4caSwyllys "[ serial=serial number]\n\t\t" 17999ebb4caSwyllys "[ label=cert-label ]\n\t\t" 18099ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 18199ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 18299ebb4caSwyllys 18399ebb4caSwyllys "delete keystore=pkcs11 objtype=key[:[public | private | both]]\n\t\t" 18499ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 18599ebb4caSwyllys "[ label=key-label ]\n\t\t" 18699ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 18799ebb4caSwyllys 18899ebb4caSwyllys "delete keystore=pkcs11 objtype=crl\n\t\t" 18999ebb4caSwyllys "infile=crl-fn\n\t\t" 19099ebb4caSwyllys "[ dir=directory-path ]\n\t" 19199ebb4caSwyllys 19299ebb4caSwyllys "delete keystore=file objtype=cert\n\t\t" 19399ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 19499ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 19599ebb4caSwyllys "[ serial=serial number]\n\t\t" 19699ebb4caSwyllys "[ infile=cert-fn ]\n\t\t" 19799ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 19899ebb4caSwyllys "[ criteria=valid|expired|both ]\n\t" 19999ebb4caSwyllys 20099ebb4caSwyllys "delete keystore=file objtype=key\n\t\t" 20199ebb4caSwyllys "[ infile=key-fn ]\n\t\t" 20299ebb4caSwyllys "[ dir=directory-path ]\n\t" 20399ebb4caSwyllys 20499ebb4caSwyllys "delete keystore=file objtype=crl\n\t\t" 20599ebb4caSwyllys "infile=crl-fn\n\t\t" 20699ebb4caSwyllys "[ dir=directory-path ]\n\t" 20799ebb4caSwyllys }, 20849e21299Sdinak { "import", pk_import, 0, 209*985be8f1Swyllys "imports objects from an external source", 21099ebb4caSwyllys 21199ebb4caSwyllys "import [token=token[:manuf[:serial]]]\n\t\t" 21299ebb4caSwyllys "infile=input-fn\n\t" 21399ebb4caSwyllys 21499ebb4caSwyllys "import keystore=nss objtype=cert\n\t\t" 21599ebb4caSwyllys "infile=input-fn\n\t\t" 21699ebb4caSwyllys "nickname=cert-nickname\n\t\t" 21799ebb4caSwyllys "[ trust=trust-value ]\n\t\t" 21899ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 21999ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 22099ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 22199ebb4caSwyllys 22299ebb4caSwyllys "import keystore=nss objtype=crl\n\t\t" 22399ebb4caSwyllys "infile=input-fn\n\t\t" 22499ebb4caSwyllys "[ verifycrl=y|n ]\n\t\t" 22599ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 22699ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 22799ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 22899ebb4caSwyllys 22999ebb4caSwyllys "import keystore=pkcs11\n\t\t" 23099ebb4caSwyllys "infile=input-fn\n\t\t" 23199ebb4caSwyllys "label=cert-label\n\t\t" 23299ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 23399ebb4caSwyllys 23499ebb4caSwyllys "import keystore=pkcs11 objtype=crl\n\t\t" 23599ebb4caSwyllys "infile=input-crl-fn\n\t\t" 23699ebb4caSwyllys "outcrl=output-crl-fn\n\t\t" 23799ebb4caSwyllys "outformat=pem|der\n\t\t" 23899ebb4caSwyllys "[ dir=output-crl-directory-path ]\n\t" 23999ebb4caSwyllys 24099ebb4caSwyllys "import keystore=file\n\t\t" 24199ebb4caSwyllys "infile=input-fn\n\t\t" 24299ebb4caSwyllys "outkey=output-key-fn\n\t\t" 24399ebb4caSwyllys "outcert=output-cert-fn\n\t\t" 24499ebb4caSwyllys "[ dir=output-cert-dir-path ]\n\t\t" 24599ebb4caSwyllys "[ keydir=output-key-dir-path ]\n\t\t" 24699ebb4caSwyllys "[ outformat=pem|der|pkcs12 ]\n\t" 24799ebb4caSwyllys 24899ebb4caSwyllys "import keystore=file objtype=crl\n\t\t" 24999ebb4caSwyllys "infile=input-crl-fn\n\t\t" 25099ebb4caSwyllys "outcrl=output-crl-fn\n\t\t" 25199ebb4caSwyllys "outformat=pem|der\n\t\t" 25299ebb4caSwyllys "[ dir=output-crl-directory-path ]\n\t" 25399ebb4caSwyllys }, 25499ebb4caSwyllys 25549e21299Sdinak { "export", pk_export, 0, 256*985be8f1Swyllys "exports objects from the keystore to a file", 25799ebb4caSwyllys 25899ebb4caSwyllys "export [token=token[:manuf[:serial]]]\n\t\t" 25999ebb4caSwyllys "outfile=output-fn\n\t" 26099ebb4caSwyllys 26199ebb4caSwyllys "export keystore=nss\n\t\t" 26299ebb4caSwyllys "outfile=output-fn\n\t\t" 26399ebb4caSwyllys "[ objtype=cert|key ]\n\t\t" 26499ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 26599ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 26699ebb4caSwyllys "[ serial=serial number]\n\t\t" 26799ebb4caSwyllys "[ nickname=cert-nickname]\n\t\t" 26899ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 26999ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 27099ebb4caSwyllys "[ prefix=DBPrefix ]\n\t\t" 27199ebb4caSwyllys "[ outformat=pem|der|pkcs12 ]\n\t" 27299ebb4caSwyllys 27399ebb4caSwyllys "export keystore=pkcs11\n\t\t" 27499ebb4caSwyllys "outfile=output-fn\n\t\t" 27599ebb4caSwyllys "[ label=cert-label]\n\t\t" 27699ebb4caSwyllys "[ subject=subject-DN ]\n\t\t" 27799ebb4caSwyllys "[ issuer=issuer-DN ]\n\t\t" 27899ebb4caSwyllys "[ serial=serial number]\n\t\t" 27999ebb4caSwyllys "[ outformat=pem|der|pkcs12]\n\t\t" 28099ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t" 28199ebb4caSwyllys 28299ebb4caSwyllys "export keystore=file\n\t\t" 28399ebb4caSwyllys "certfile=cert-input-fn\n\t\t" 28499ebb4caSwyllys "keyfile=key-input-fn\n\t\t" 28599ebb4caSwyllys "outfile=output-pkcs12-fn\n\t\t" 28699ebb4caSwyllys "[ dir=directory-path ]\n\t" 28799ebb4caSwyllys }, 28899ebb4caSwyllys 28999ebb4caSwyllys { "gencert", pk_gencert, 0, 290*985be8f1Swyllys "creates a self-signed X.509v3 certificate", 291*985be8f1Swyllys 29299ebb4caSwyllys "gencert [-i] keystore=nss\n\t\t" 29399ebb4caSwyllys "label=cert-nickname\n\t\t" 29499ebb4caSwyllys "serial=serial number hex string]\n\t\t" 29599ebb4caSwyllys "subject=subject-DN\n\t\t" 29699ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 29799ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 29899ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 29999ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 30099ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 30199ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 30299ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 30399ebb4caSwyllys "[ trust=trust-value ]\n\t\t" 30499ebb4caSwyllys "[ lifetime=number-hour|number-day|number-year ]\n\t" 30599ebb4caSwyllys 30699ebb4caSwyllys "gencert [-i] [ keystore=pkcs11 ]\n\t\t" 30799ebb4caSwyllys "label=key/cert-label\n\t\t" 30899ebb4caSwyllys "subject=subject-DN\n\t\t" 30999ebb4caSwyllys "serial=serial number hex string\n\t\t" 31099ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 31199ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 31299ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 31399ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 31499ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 31599ebb4caSwyllys "[ lifetime=number-hour|number-day|number-year ]\n\t" 31699ebb4caSwyllys 31799ebb4caSwyllys "gencert [-i] keystore=file\n\t\t" 31899ebb4caSwyllys "outcert=cert_filename\n\t\t" 31999ebb4caSwyllys "outkey=key_filename\n\t\t" 32099ebb4caSwyllys "subject=subject-DN\n\t\t" 32199ebb4caSwyllys "serial=serial number hex string\n\t\t" 32299ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 32399ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 32499ebb4caSwyllys "[ format=der|pem ]\n\t\t" 32599ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 32699ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 32799ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 32899ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 32999ebb4caSwyllys "[ lifetime=number-hour|number-day|number-year ]\n\t" 33099ebb4caSwyllys }, 33199ebb4caSwyllys { "gencsr", pk_gencsr, 0, 332*985be8f1Swyllys "creates a PKCS#10 certificate signing request file", 33399ebb4caSwyllys "gencsr [-i] keystore=nss \n\t\t" 33499ebb4caSwyllys "nickname=cert-nickname\n\t\t" 33599ebb4caSwyllys "outcsr=csr-fn\n\t\t" 33699ebb4caSwyllys "subject=subject-DN\n\t\t" 33799ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 33899ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 33999ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 34099ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 34199ebb4caSwyllys "[ prefix=DBprefix ]\n\t\t" 34299ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 34399ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 34499ebb4caSwyllys "[ format=pem|der]\n\t" 34599ebb4caSwyllys "gencsr [-i] [ keystore=pkcs11 ]\n\t\t" 34699ebb4caSwyllys "label=key-label\n\t\t" 34799ebb4caSwyllys "outcsr=csr-fn\n\t\t" 34899ebb4caSwyllys "subject=subject-DN\n\t\t" 34999ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 35099ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 35199ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 35299ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 35399ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 35499ebb4caSwyllys "[ format=pem|der]\n\t" 35599ebb4caSwyllys "gencsr [-i] keystore=file\n\t\t" 35699ebb4caSwyllys "outcsr=csr-fn\n\t\t" 35799ebb4caSwyllys "outkey=key-fn\n\t\t" 35899ebb4caSwyllys "subject=subject-DN\n\t\t" 35999ebb4caSwyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" 36099ebb4caSwyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" 36199ebb4caSwyllys "[ keytype=rsa|dsa ]\n\t\t" 36299ebb4caSwyllys "[ keylen=key-size ]\n\t\t" 36399ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 36499ebb4caSwyllys "[ format=pem|der]\n\t" 36599ebb4caSwyllys }, 36699ebb4caSwyllys 36799ebb4caSwyllys { "download", pk_download, 0, 368*985be8f1Swyllys "downloads a CRL or certificate file from an external source", 369*985be8f1Swyllys 37099ebb4caSwyllys "download url=url_str\n\t\t" 37199ebb4caSwyllys "[ objtype=crl|cert ]\n\t\t" 37299ebb4caSwyllys "[ http_proxy=proxy_str ]\n\t\t" 37399ebb4caSwyllys "[ outfile = outfile ]\n\t\t" 37499ebb4caSwyllys }, 37599ebb4caSwyllys 37699ebb4caSwyllys { "genkey", pk_genkey, 0, 377*985be8f1Swyllys "creates a symmetric key in the keystore", 378*985be8f1Swyllys 37999ebb4caSwyllys "genkey [ keystore=pkcs11 ]\n\t\t" 38099ebb4caSwyllys "label=key-label\n\t\t" 38199ebb4caSwyllys "[ keytype=aes|arcfour|des|3des ]\n\t\t" 38299ebb4caSwyllys "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" 38399ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 38499ebb4caSwyllys "[ sensitive=y|n ]\n\t\t" 38599ebb4caSwyllys "[ extractable=y|n ]\n\t\t" 38699ebb4caSwyllys "[ print=y|n ]\n\t" 38799ebb4caSwyllys 38899ebb4caSwyllys "genkey keystore=nss\n\t\t" 38999ebb4caSwyllys "label=key-label\n\t\t" 39099ebb4caSwyllys "[ keytype=aes|arcfour|des|3des ]\n\t\t" 39199ebb4caSwyllys "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" 39299ebb4caSwyllys "[ token=token[:manuf[:serial]]]\n\t\t" 39399ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 39499ebb4caSwyllys "[ prefix=DBprefix ]\n\t" 39599ebb4caSwyllys 39699ebb4caSwyllys "genkey keystore=file\n\t\t" 39799ebb4caSwyllys "outkey=key-fn\n\t\t" 39899ebb4caSwyllys "[ keytype=aes|arcfour|des|3des ]\n\t\t" 39999ebb4caSwyllys "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" 40099ebb4caSwyllys "[ dir=directory-path ]\n\t\t" 40199ebb4caSwyllys "[ print=y|n ]\n\t" 40299ebb4caSwyllys }, 40399ebb4caSwyllys 404*985be8f1Swyllys { "help", pk_help, 0, 405*985be8f1Swyllys "displays help message", 406*985be8f1Swyllys "help\t(help and usage)" } 4077c478bd9Sstevel@tonic-gate }; 408*985be8f1Swyllys 4097c478bd9Sstevel@tonic-gate static int num_cmds = sizeof (cmds) / sizeof (verbcmd); 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate static char *prog; 41299ebb4caSwyllys static void usage(int); 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate /* 4157c478bd9Sstevel@tonic-gate * Usage information. This function must be updated when new verbs or 4167c478bd9Sstevel@tonic-gate * options are added. 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate static void 41999ebb4caSwyllys usage(int idx) 4207c478bd9Sstevel@tonic-gate { 4217711facfSdinak int i; 4227711facfSdinak 4237711facfSdinak /* Display this block only in command-line mode. */ 4247711facfSdinak (void) fprintf(stdout, gettext("Usage:\n")); 425*985be8f1Swyllys (void) fprintf(stdout, gettext(" %s -?\t(help and usage)\n"), 426*985be8f1Swyllys prog); 427*985be8f1Swyllys (void) fprintf(stdout, gettext(" %s -f option_file\n"), prog); 428*985be8f1Swyllys (void) fprintf(stdout, gettext(" %s subcommand [options...]\n"), 429*985be8f1Swyllys prog); 4307711facfSdinak (void) fprintf(stdout, gettext("where subcommands may be:\n")); 4317711facfSdinak 4327711facfSdinak /* Display only those verbs that match the current tool mode. */ 43399ebb4caSwyllys if (idx == -1) { 4347711facfSdinak for (i = 0; i < num_cmds; i++) { 4357711facfSdinak /* Do NOT i18n/l10n. */ 436*985be8f1Swyllys (void) fprintf(stdout, " %-8s - %s\n", 437*985be8f1Swyllys cmds[i].verb, cmds[i].summary); 4387711facfSdinak } 439*985be8f1Swyllys (void) fprintf(stdout, gettext("\nFurther details on the " 440*985be8f1Swyllys "subcommands can be found by adding \'help\'.\n" 441*985be8f1Swyllys "Ex: pktool gencert help\n\n")); 44299ebb4caSwyllys } else { 44399ebb4caSwyllys (void) fprintf(stdout, "\t%s\n", cmds[idx].synopsis); 44499ebb4caSwyllys } 4457711facfSdinak } 4467711facfSdinak 4477711facfSdinak /* 4487711facfSdinak * Provide help, in the form of displaying the usage. 4497711facfSdinak */ 4507711facfSdinak static int 4517711facfSdinak pk_help(int argc, char *argv[]) 4527711facfSdinak /* ARGSUSED */ 4537711facfSdinak { 45499ebb4caSwyllys usage(-1); 45599ebb4caSwyllys return (0); 45699ebb4caSwyllys } 4577711facfSdinak 45899ebb4caSwyllys /* 45999ebb4caSwyllys * Process arguments from the argfile and create a new 46099ebb4caSwyllys * argv/argc list to be processed later. 46199ebb4caSwyllys */ 46299ebb4caSwyllys static int 46399ebb4caSwyllys process_arg_file(char *argfile, char ***argv, int *argc) 46499ebb4caSwyllys { 46599ebb4caSwyllys FILE *fp; 46699ebb4caSwyllys char argline[2 * BUFSIZ]; /* 2048 bytes should be plenty */ 46799ebb4caSwyllys char *p; 46899ebb4caSwyllys int nargs = 0; 46999ebb4caSwyllys 47099ebb4caSwyllys if ((fp = fopen(argfile, "rF")) == NULL) { 47199ebb4caSwyllys (void) fprintf(stderr, 47299ebb4caSwyllys gettext("Cannot read argfile %s: %s\n"), 47399ebb4caSwyllys argfile, strerror(errno)); 47499ebb4caSwyllys return (errno); 47599ebb4caSwyllys } 47699ebb4caSwyllys 47799ebb4caSwyllys while (fgets(argline, sizeof (argline), fp) != NULL) { 47899ebb4caSwyllys int j; 47999ebb4caSwyllys /* remove trailing whitespace */ 48099ebb4caSwyllys j = strlen(argline) - 1; 48199ebb4caSwyllys while (j >= 0 && isspace(argline[j])) { 48299ebb4caSwyllys argline[j] = 0; 48399ebb4caSwyllys j--; 48499ebb4caSwyllys } 48599ebb4caSwyllys /* If it was a blank line, get the next one. */ 48699ebb4caSwyllys if (!strlen(argline)) 48799ebb4caSwyllys continue; 48899ebb4caSwyllys 48999ebb4caSwyllys (*argv) = realloc((*argv), 49099ebb4caSwyllys (nargs + 1) * sizeof (char *)); 49199ebb4caSwyllys if ((*argv) == NULL) { 49299ebb4caSwyllys perror("memory error"); 49399ebb4caSwyllys (void) fclose(fp); 49499ebb4caSwyllys return (errno); 49599ebb4caSwyllys } 49699ebb4caSwyllys p = (char *)strdup(argline); 49799ebb4caSwyllys if (p == NULL) { 49899ebb4caSwyllys perror("memory error"); 49999ebb4caSwyllys (void) fclose(fp); 50099ebb4caSwyllys return (errno); 50199ebb4caSwyllys } 50299ebb4caSwyllys (*argv)[nargs] = p; 50399ebb4caSwyllys nargs++; 50499ebb4caSwyllys } 50599ebb4caSwyllys *argc = nargs; 50699ebb4caSwyllys (void) fclose(fp); 5077711facfSdinak return (0); 5087c478bd9Sstevel@tonic-gate } 5097c478bd9Sstevel@tonic-gate 5107c478bd9Sstevel@tonic-gate /* 5117c478bd9Sstevel@tonic-gate * MAIN() -- where all the action is 5127c478bd9Sstevel@tonic-gate */ 5137c478bd9Sstevel@tonic-gate int 5147c478bd9Sstevel@tonic-gate main(int argc, char *argv[], char *envp[]) 5157c478bd9Sstevel@tonic-gate /* ARGSUSED2 */ 5167c478bd9Sstevel@tonic-gate { 5177c478bd9Sstevel@tonic-gate int i, found = -1; 5187c478bd9Sstevel@tonic-gate int rv; 5197c478bd9Sstevel@tonic-gate int pk_argc = 0; 5207c478bd9Sstevel@tonic-gate char **pk_argv = NULL; 5217711facfSdinak int save_errno = 0; 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate /* Set up for i18n/l10n. */ 5247c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 5257c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D. */ 5267c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't. */ 5277c478bd9Sstevel@tonic-gate #endif 5287c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate /* Get program base name and move pointer over 0th arg. */ 5317c478bd9Sstevel@tonic-gate prog = basename(argv[0]); 5327c478bd9Sstevel@tonic-gate argv++, argc--; 5337c478bd9Sstevel@tonic-gate 5347c478bd9Sstevel@tonic-gate /* Set up for debug and error output. */ 5357c478bd9Sstevel@tonic-gate if (argc == 0) { 53699ebb4caSwyllys usage(-1); 5377c478bd9Sstevel@tonic-gate return (1); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5407711facfSdinak /* Check for help options. For CLIP-compliance. */ 54199ebb4caSwyllys if (strcmp(argv[0], "-?") == 0) { 5427711facfSdinak return (pk_help(argc, argv)); 54399ebb4caSwyllys } else if (strcmp(argv[0], "-f") == 0 && argc == 2) { 54499ebb4caSwyllys rv = process_arg_file(argv[1], &pk_argv, &pk_argc); 54599ebb4caSwyllys if (rv) 54699ebb4caSwyllys return (rv); 54799ebb4caSwyllys } else if (argc >= 1 && argv[0][0] == '-') { 54899ebb4caSwyllys usage(-1); 5497711facfSdinak return (1); 5507711facfSdinak } 5517711facfSdinak 5527711facfSdinak /* Always turns off Metaslot so that we can see softtoken. */ 5537c478bd9Sstevel@tonic-gate if (setenv("METASLOT_ENABLED", "false", 1) < 0) { 5547711facfSdinak save_errno = errno; 5557c478bd9Sstevel@tonic-gate cryptoerror(LOG_STDERR, 5567711facfSdinak gettext("Disabling Metaslot failed (%s)."), 5577711facfSdinak strerror(save_errno)); 5587c478bd9Sstevel@tonic-gate return (1); 5597c478bd9Sstevel@tonic-gate } 5607c478bd9Sstevel@tonic-gate 5617c478bd9Sstevel@tonic-gate /* Begin parsing command line. */ 56299ebb4caSwyllys if (pk_argc == 0 && pk_argv == NULL) { 5637c478bd9Sstevel@tonic-gate pk_argc = argc; 5647c478bd9Sstevel@tonic-gate pk_argv = argv; 56599ebb4caSwyllys } 5667c478bd9Sstevel@tonic-gate 5677711facfSdinak /* Check for valid verb (or an abbreviation of it). */ 5687c478bd9Sstevel@tonic-gate found = -1; 5697c478bd9Sstevel@tonic-gate for (i = 0; i < num_cmds; i++) { 5707c478bd9Sstevel@tonic-gate if (strcmp(cmds[i].verb, pk_argv[0]) == 0) { 5717c478bd9Sstevel@tonic-gate if (found < 0) { 5727c478bd9Sstevel@tonic-gate found = i; 5737c478bd9Sstevel@tonic-gate break; 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate /* Stop here if no valid verb found. */ 5787c478bd9Sstevel@tonic-gate if (found < 0) { 5797711facfSdinak cryptoerror(LOG_STDERR, gettext("Invalid verb: %s"), 5807711facfSdinak pk_argv[0]); 5817c478bd9Sstevel@tonic-gate return (1); 5827c478bd9Sstevel@tonic-gate } 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate /* Get to work! */ 5857c478bd9Sstevel@tonic-gate rv = (*cmds[found].action)(pk_argc, pk_argv); 5867c478bd9Sstevel@tonic-gate switch (rv) { 5877c478bd9Sstevel@tonic-gate case PK_ERR_NONE: 5887c478bd9Sstevel@tonic-gate break; /* Command succeeded, do nothing. */ 5897c478bd9Sstevel@tonic-gate case PK_ERR_USAGE: 59099ebb4caSwyllys usage(found); 5917c478bd9Sstevel@tonic-gate break; 5927c478bd9Sstevel@tonic-gate case PK_ERR_QUIT: 5937c478bd9Sstevel@tonic-gate exit(0); 5947c478bd9Sstevel@tonic-gate /* NOTREACHED */ 5957711facfSdinak case PK_ERR_PK11: 5967711facfSdinak case PK_ERR_SYSTEM: 5977711facfSdinak case PK_ERR_OPENSSL: 59899ebb4caSwyllys case PK_ERR_NSS: 5997c478bd9Sstevel@tonic-gate default: 6007c478bd9Sstevel@tonic-gate break; 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate return (rv); 6037c478bd9Sstevel@tonic-gate } 604