diff options
Diffstat (limited to 'usr/src/cmd/cmd-crypto/pktool/pktool.c')
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/pktool.c | 455 |
1 files changed, 398 insertions, 57 deletions
diff --git a/usr/src/cmd/cmd-crypto/pktool/pktool.c b/usr/src/cmd/cmd-crypto/pktool/pktool.c index ce7a26235c..c97cf80063 100644 --- a/usr/src/cmd/cmd-crypto/pktool/pktool.c +++ b/usr/src/cmd/cmd-crypto/pktool/pktool.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -62,6 +61,10 @@ extern int pk_delete(int argc, char *argv[]); extern int pk_import(int argc, char *argv[]); extern int pk_export(int argc, char *argv[]); extern int pk_tokens(int argc, char *argv[]); +extern int pk_gencert(int argc, char *argv[]); +extern int pk_gencsr(int argc, char *argv[]); +extern int pk_download(int argc, char *argv[]); +extern int pk_genkey(int argc, char *argv[]); /* Forward declarations for "built-in" verb actions. */ static int pk_help(int argc, char *argv[]); @@ -70,45 +73,353 @@ static int pk_help(int argc, char *argv[]); static verbcmd cmds[] = { { "tokens", pk_tokens, 0, "tokens" }, { "setpin", pk_setpin, 0, - "setpin [token=<token>[:<manuf>[:<serial>]]]" }, + "setpin [ keystore=pkcs11 ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t" + + "setpin keystore=nss\n\t\t" + "[ token=token ]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t" + }, { "list", pk_list, 0, - "list [token=<token>[:<manuf>[:<serial>]]] " - "[objtype=private|public|both] [label=<label>]" }, + + "list [ token=token[:manuf[:serial]]]\n\t\t" + "[ objtype=private|public|both ]\n\t\t" + "[ label=label ]\n\t" + + "list objtype=cert[:[public | private | both ]]\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ keystore=pkcs11 ]\n\t\t" + "[ issuer=issuer-DN ]\n\t\t" + "[ serial=serial number]\n\t\t" + "[ label=cert-label ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ criteria=valid|expired|both ]\n\t" + + "list objtype=key[:[public | private | both ]]\n\t\t" + "[ keystore=pkcs11 ]\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ label=key-label ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t" + + "list keystore=pkcs11 objtype=crl\n\t\t" + "infile=crl-fn\n\t\t" + "[ dir=directory-path ]\n\t" + + "list keystore=nss objtype=cert\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ issuer=issuer-DN ]\n\t\t" + "[ serial=serial number]\n\t\t" + "[ nickname=cert-nickname ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t\t" + "[ criteria=valid|expired|both ]\n\t" + + "list keystore=nss objtype=key\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t\t" + "[ nickname=key-nickname ]\n\t" + + "list keystore=file objtype=cert\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ issuer=issuer-DN ]\n\t\t" + "[ serial=serial number]\n\t\t" + "[ infile=cert-fn ]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ criteria=valid|expired|both ]\n\t" + + "list keystore=file objtype=key\n\t\t" + "[ infile=key-fn ]\n\t\t" + "[ dir=directory-path ]\n\t" + + "list keystore=file objtype=crl\n\t\t" + "infile=crl-fn\n\t\t" + "[ dir=directory-path ]\n\t" + }, + { "delete", pk_delete, 0, - "delete [token=<token>[:<manuf>[:<serial>]]] " - "{ [objtype=private|public|both] [label=<label>] }" }, + + "delete [ token=token[:manuf[:serial]]]\n\t\t" + "[ objtype=private|public|both ]\n\t\t" + "[ label=object-label ]\n\t" + + "delete keystore=nss objtype=cert\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ issuer=issuer-DN ]\n\t\t" + "[ serial=serial number]\n\t\t" + "[ nickname=cert-nickname ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t\t" + "[ criteria=valid|expired|both ]\n\t" + + "delete keystore=nss objtype=key\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t\t" + "[ nickname=key-nickname ]\n\t\t" + + "delete keystore=nss objtype=crl\n\t\t" + "[ nickname=issuer-nickname ]\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t" + + "delete keystore=pkcs11 objtype=cert[:[public | private | both]]\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ issuer=issuer-DN ]\n\t\t" + "[ serial=serial number]\n\t\t" + "[ label=cert-label ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ criteria=valid|expired|both ]\n\t" + + "delete keystore=pkcs11 objtype=key[:[public | private | both]]\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ label=key-label ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t" + + "delete keystore=pkcs11 objtype=crl\n\t\t" + "infile=crl-fn\n\t\t" + "[ dir=directory-path ]\n\t" + + "delete keystore=file objtype=cert\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ issuer=issuer-DN ]\n\t\t" + "[ serial=serial number]\n\t\t" + "[ infile=cert-fn ]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ criteria=valid|expired|both ]\n\t" + + "delete keystore=file objtype=key\n\t\t" + "[ infile=key-fn ]\n\t\t" + "[ dir=directory-path ]\n\t" + + "delete keystore=file objtype=crl\n\t\t" + "infile=crl-fn\n\t\t" + "[ dir=directory-path ]\n\t" + }, { "import", pk_import, 0, - "import [token=<token>[:<manuf>[:<serial>]]] infile=<file>" }, + + "import [token=token[:manuf[:serial]]]\n\t\t" + "infile=input-fn\n\t" + + "import keystore=nss objtype=cert\n\t\t" + "infile=input-fn\n\t\t" + "nickname=cert-nickname\n\t\t" + "[ trust=trust-value ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t" + + "import keystore=nss objtype=crl\n\t\t" + "infile=input-fn\n\t\t" + "[ verifycrl=y|n ]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t" + + "import keystore=pkcs11\n\t\t" + "infile=input-fn\n\t\t" + "label=cert-label\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t" + + "import keystore=pkcs11 objtype=crl\n\t\t" + "infile=input-crl-fn\n\t\t" + "outcrl=output-crl-fn\n\t\t" + "outformat=pem|der\n\t\t" + "[ dir=output-crl-directory-path ]\n\t" + + "import keystore=file\n\t\t" + "infile=input-fn\n\t\t" + "outkey=output-key-fn\n\t\t" + "outcert=output-cert-fn\n\t\t" + "[ dir=output-cert-dir-path ]\n\t\t" + "[ keydir=output-key-dir-path ]\n\t\t" + "[ outformat=pem|der|pkcs12 ]\n\t" + + "import keystore=file objtype=crl\n\t\t" + "infile=input-crl-fn\n\t\t" + "outcrl=output-crl-fn\n\t\t" + "outformat=pem|der\n\t\t" + "[ dir=output-crl-directory-path ]\n\t" + }, + { "export", pk_export, 0, - "export [token=<token>[:<manuf>[:<serial>]]] outfile=<file>" }, - { "-?", pk_help, 0, "help\t(help and usage)" }, + + "export [token=token[:manuf[:serial]]]\n\t\t" + "outfile=output-fn\n\t" + + "export keystore=nss\n\t\t" + "outfile=output-fn\n\t\t" + "[ objtype=cert|key ]\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ issuer=issuer-DN ]\n\t\t" + "[ serial=serial number]\n\t\t" + "[ nickname=cert-nickname]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBPrefix ]\n\t\t" + "[ outformat=pem|der|pkcs12 ]\n\t" + + "export keystore=pkcs11\n\t\t" + "outfile=output-fn\n\t\t" + "[ label=cert-label]\n\t\t" + "[ subject=subject-DN ]\n\t\t" + "[ issuer=issuer-DN ]\n\t\t" + "[ serial=serial number]\n\t\t" + "[ outformat=pem|der|pkcs12]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t" + + "export keystore=file\n\t\t" + "certfile=cert-input-fn\n\t\t" + "keyfile=key-input-fn\n\t\t" + "outfile=output-pkcs12-fn\n\t\t" + "[ dir=directory-path ]\n\t" + }, + + { "gencert", pk_gencert, 0, + "gencert [-i] keystore=nss\n\t\t" + "label=cert-nickname\n\t\t" + "serial=serial number hex string]\n\t\t" + "subject=subject-DN\n\t\t" + "[ altname=[critical:]SubjectAltName ]\n\t\t" + "[ keyusage=[critical:]usage,usage,...]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t\t" + "[ keytype=rsa|dsa ]\n\t\t" + "[ keylen=key-size ]\n\t\t" + "[ trust=trust-value ]\n\t\t" + "[ lifetime=number-hour|number-day|number-year ]\n\t" + + "gencert [-i] [ keystore=pkcs11 ]\n\t\t" + "label=key/cert-label\n\t\t" + "subject=subject-DN\n\t\t" + "serial=serial number hex string\n\t\t" + "[ altname=[critical:]SubjectAltName ]\n\t\t" + "[ keyusage=[critical:]usage,usage,...]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ keytype=rsa|dsa ]\n\t\t" + "[ keylen=key-size ]\n\t\t" + "[ lifetime=number-hour|number-day|number-year ]\n\t" + + "gencert [-i] keystore=file\n\t\t" + "outcert=cert_filename\n\t\t" + "outkey=key_filename\n\t\t" + "subject=subject-DN\n\t\t" + "serial=serial number hex string\n\t\t" + "[ altname=[critical:]SubjectAltName ]\n\t\t" + "[ keyusage=[critical:]usage,usage,...]\n\t\t" + "[ format=der|pem ]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t\t" + "[ keytype=rsa|dsa ]\n\t\t" + "[ keylen=key-size ]\n\t\t" + "[ lifetime=number-hour|number-day|number-year ]\n\t" + }, + { "gencsr", pk_gencsr, 0, + "gencsr [-i] keystore=nss \n\t\t" + "nickname=cert-nickname\n\t\t" + "outcsr=csr-fn\n\t\t" + "subject=subject-DN\n\t\t" + "[ altname=[critical:]SubjectAltName ]\n\t\t" + "[ keyusage=[critical:]usage,usage,...]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t\t" + "[ keytype=rsa|dsa ]\n\t\t" + "[ keylen=key-size ]\n\t\t" + "[ format=pem|der]\n\t" + "gencsr [-i] [ keystore=pkcs11 ]\n\t\t" + "label=key-label\n\t\t" + "outcsr=csr-fn\n\t\t" + "subject=subject-DN\n\t\t" + "[ altname=[critical:]SubjectAltName ]\n\t\t" + "[ keyusage=[critical:]usage,usage,...]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ keytype=rsa|dsa ]\n\t\t" + "[ keylen=key-size ]\n\t\t" + "[ format=pem|der]\n\t" + "gencsr [-i] keystore=file\n\t\t" + "outcsr=csr-fn\n\t\t" + "outkey=key-fn\n\t\t" + "subject=subject-DN\n\t\t" + "[ altname=[critical:]SubjectAltName ]\n\t\t" + "[ keyusage=[critical:]usage,usage,...]\n\t\t" + "[ keytype=rsa|dsa ]\n\t\t" + "[ keylen=key-size ]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ format=pem|der]\n\t" + }, + + { "download", pk_download, 0, + "download url=url_str\n\t\t" + "[ objtype=crl|cert ]\n\t\t" + "[ http_proxy=proxy_str ]\n\t\t" + "[ outfile = outfile ]\n\t\t" + }, + + { "genkey", pk_genkey, 0, + "genkey [ keystore=pkcs11 ]\n\t\t" + "label=key-label\n\t\t" + "[ keytype=aes|arcfour|des|3des ]\n\t\t" + "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ sensitive=y|n ]\n\t\t" + "[ extractable=y|n ]\n\t\t" + "[ print=y|n ]\n\t" + + "genkey keystore=nss\n\t\t" + "label=key-label\n\t\t" + "[ keytype=aes|arcfour|des|3des ]\n\t\t" + "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" + "[ token=token[:manuf[:serial]]]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ prefix=DBprefix ]\n\t" + + "genkey keystore=file\n\t\t" + "outkey=key-fn\n\t\t" + "[ keytype=aes|arcfour|des|3des ]\n\t\t" + "[ keylen=key-size (AES or ARCFOUR only)]\n\t\t" + "[ dir=directory-path ]\n\t\t" + "[ print=y|n ]\n\t" + }, + + { "-?", pk_help, 0, "help\t(help and usage)" }, + { "-f", pk_help, 0, "-f option_file" } }; static int num_cmds = sizeof (cmds) / sizeof (verbcmd); static char *prog; -static void usage(void); +static void usage(int); /* * Usage information. This function must be updated when new verbs or * options are added. */ static void -usage(void) +usage(int idx) { int i; - cryptodebug("inside usage"); - /* Display this block only in command-line mode. */ (void) fprintf(stdout, gettext("Usage:\n")); (void) fprintf(stdout, gettext("\t%s -?\t(help and usage)\n"), prog); + (void) fprintf(stdout, gettext("\t%s -f option_file\n"), prog); (void) fprintf(stdout, gettext("\t%s subcommand [options...]\n"), prog); (void) fprintf(stdout, gettext("where subcommands may be:\n")); /* Display only those verbs that match the current tool mode. */ - for (i = 0; i < num_cmds; i++) { - /* Do NOT i18n/l10n. */ - (void) fprintf(stdout, "\t%s\n", cmds[i].synopsis); + if (idx == -1) { + for (i = 0; i < num_cmds; i++) { + /* Do NOT i18n/l10n. */ + (void) fprintf(stdout, "\t%s\n", cmds[i].synopsis); + } + } else { + (void) fprintf(stdout, "\t%s\n", cmds[idx].synopsis); } } @@ -119,9 +430,59 @@ static int pk_help(int argc, char *argv[]) /* ARGSUSED */ { - cryptodebug("inside pk_help"); + usage(-1); + return (0); +} + +/* + * Process arguments from the argfile and create a new + * argv/argc list to be processed later. + */ +static int +process_arg_file(char *argfile, char ***argv, int *argc) +{ + FILE *fp; + char argline[2 * BUFSIZ]; /* 2048 bytes should be plenty */ + char *p; + int nargs = 0; + + if ((fp = fopen(argfile, "rF")) == NULL) { + (void) fprintf(stderr, + gettext("Cannot read argfile %s: %s\n"), + argfile, strerror(errno)); + return (errno); + } - usage(); + while (fgets(argline, sizeof (argline), fp) != NULL) { + int j; + /* remove trailing whitespace */ + j = strlen(argline) - 1; + while (j >= 0 && isspace(argline[j])) { + argline[j] = 0; + j--; + } + /* If it was a blank line, get the next one. */ + if (!strlen(argline)) + continue; + + (*argv) = realloc((*argv), + (nargs + 1) * sizeof (char *)); + if ((*argv) == NULL) { + perror("memory error"); + (void) fclose(fp); + return (errno); + } + p = (char *)strdup(argline); + if (p == NULL) { + perror("memory error"); + (void) fclose(fp); + return (errno); + } + (*argv)[nargs] = p; + nargs++; + } + *argc = nargs; + (void) fclose(fp); return (0); } @@ -150,26 +511,24 @@ main(int argc, char *argv[], char *envp[]) argv++, argc--; /* Set up for debug and error output. */ - cryptodebug_init(prog); - if (argc == 0) { - usage(); + usage(-1); return (1); } /* Check for help options. For CLIP-compliance. */ - if (argc == 1 && argv[0][0] == '-') { - switch (argv[0][1]) { - case '?': - return (pk_help(argc, argv)); - default: - usage(); - return (1); - } + if (strcmp(argv[0], "-?") == 0) { + return (pk_help(argc, argv)); + } else if (strcmp(argv[0], "-f") == 0 && argc == 2) { + rv = process_arg_file(argv[1], &pk_argv, &pk_argc); + if (rv) + return (rv); + } else if (argc >= 1 && argv[0][0] == '-') { + usage(-1); + return (1); } /* Always turns off Metaslot so that we can see softtoken. */ - cryptodebug("disabling Metaslot"); if (setenv("METASLOT_ENABLED", "false", 1) < 0) { save_errno = errno; cryptoerror(LOG_STDERR, @@ -179,21 +538,18 @@ main(int argc, char *argv[], char *envp[]) } /* Begin parsing command line. */ - cryptodebug("begin parsing command line"); - pk_argc = argc; - pk_argv = argv; + if (pk_argc == 0 && pk_argv == NULL) { + pk_argc = argc; + pk_argv = argv; + } /* Check for valid verb (or an abbreviation of it). */ found = -1; for (i = 0; i < num_cmds; i++) { if (strcmp(cmds[i].verb, pk_argv[0]) == 0) { if (found < 0) { - cryptodebug("found cmd %s", cmds[i].verb); found = i; break; - } else { - cryptodebug("also found cmd %s, skipping", - cmds[i].verb); } } } @@ -205,36 +561,21 @@ main(int argc, char *argv[], char *envp[]) } /* Get to work! */ - cryptodebug("begin executing cmd action"); rv = (*cmds[found].action)(pk_argc, pk_argv); - cryptodebug("end executing cmd action"); switch (rv) { case PK_ERR_NONE: - cryptodebug("subcommand succeeded"); break; /* Command succeeded, do nothing. */ case PK_ERR_USAGE: - cryptodebug("usage error detected"); - usage(); + usage(found); break; case PK_ERR_QUIT: - cryptodebug("quit command received"); exit(0); /* NOTREACHED */ case PK_ERR_PK11: - cryptoerror(LOG_STDERR, "%s", - gettext("Command failed due to PKCS#11 error.")); - break; case PK_ERR_SYSTEM: - cryptoerror(LOG_STDERR, "%s", - gettext("Command failed due to system error.")); - break; case PK_ERR_OPENSSL: - cryptoerror(LOG_STDERR, "%s", - gettext("Command failed due to OpenSSL error.")); - break; + case PK_ERR_NSS: default: - cryptoerror(LOG_STDERR, "%s (%d).", - gettext("Unknown error value"), rv); break; } return (rv); |