Mercurial > illumos > illumos-gate
changeset 864:75df3e9f93de
PSARC/2005/290 pktool(1) alternate token support
PSARC/2005/634 pktool CLI update
6288840 pktool(1) alternate token support
6332420 change pktool CLI to use attr=value format
author | dinak |
---|---|
date | Mon, 07 Nov 2005 17:38:08 -0800 |
parents | 56b591ba4423 |
children | 4223fbdac5f3 |
files | usr/src/cmd/cmd-crypto/pktool/common.c usr/src/cmd/cmd-crypto/pktool/common.h usr/src/cmd/cmd-crypto/pktool/delete.c usr/src/cmd/cmd-crypto/pktool/export.c usr/src/cmd/cmd-crypto/pktool/import.c usr/src/cmd/cmd-crypto/pktool/list.c usr/src/cmd/cmd-crypto/pktool/pktool.c usr/src/cmd/cmd-crypto/pktool/setpin.c |
diffstat | 8 files changed, 491 insertions(+), 92 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/cmd-crypto/pktool/common.c Mon Nov 07 17:36:34 2005 -0800 +++ b/usr/src/cmd/cmd-crypto/pktool/common.c Mon Nov 07 17:38:08 2005 -0800 @@ -53,6 +53,20 @@ static boolean_t session_writable = B_FALSE; static boolean_t logged_in = B_FALSE; +/* Supporting structures and global variables for getopt_av(). */ +typedef struct av_opts_s { + int shortnm; /* short name character */ + char *longnm; /* long name string, NOT terminated */ + int longnm_len; /* length of long name string */ + boolean_t has_arg; /* takes optional argument */ +} av_opts; +static av_opts *opts_av = NULL; +static const char *_save_optstr = NULL; +static int _save_numopts = 0; + +int optind_av = 1; +char *optarg_av = NULL; + /* * Perform PKCS#11 setup here. Currently only C_Initialize is required, * along with setting/resetting state variables. @@ -604,6 +618,120 @@ } /* + * Returns pointer to either null-terminator or next unescaped colon. The + * string to be extracted starts at the beginning and goes until one character + * before this pointer. If NULL is returned, the string itself is NULL. + */ +static char * +find_unescaped_colon(char *str) +{ + char *end; + + if (str == NULL) + return (NULL); + + while ((end = strchr(str, ':')) != NULL) { + if (end != str && *(end-1) != '\\') + return (end); + str = end + 1; /* could point to null-terminator */ + } + if (end == NULL) + end = strchr(str, '\0'); + return (end); +} + +/* + * Compresses away any characters escaped with backslash from given string. + * The string is altered in-place. Example, "ab\:\\e" becomes "ab:\e". + */ +static void +unescape_str(char *str) +{ + boolean_t escaped = B_FALSE; + char *mark; + + if (str == NULL) + return; + + for (mark = str; *str != '\0'; str++) { + if (*str != '\\' || escaped == B_TRUE) { + *mark++ = *str; + escaped = B_FALSE; + } else { + escaped = B_TRUE; + } + } + *mark = '\0'; +} + +/* + * Given a colon-separated token specifier, this functions splits it into + * its label, manufacturer ID (if any), and serial number (if any). Literal + * colons within the label/manuf/serial can be escaped with a backslash. + * Fields can left blank and trailing colons can be omitted, however leading + * colons are required as placeholders. For example, these are equivalent: + * (a) "lbl", "lbl:", "lbl::" (b) "lbl:man", "lbl:man:" + * but these are not: + * (c) "man", ":man" (d) "ser", "::ser" + * Furthermore, the token label is required always. + * + * The buffer containing the token specifier is altered by replacing the + * colons to null-terminators, and pointers returned are pointers into this + * string. No new memory is allocated. + */ +int +parse_token_spec(char *token_spec, char **token_name, char **manuf_id, + char **serial_no) +{ + char *mark; + + if (token_spec == NULL || *token_spec == '\0') { + cryptodebug("token specifier is empty"); + return (-1); + } + + *token_name = NULL; + *manuf_id = NULL; + *serial_no = NULL; + + /* Token label (required) */ + mark = find_unescaped_colon(token_spec); + *token_name = token_spec; + if (*mark != '\0') + *mark++ = '\0'; /* mark points to next field, if any */ + unescape_str(*token_name); + + if (*(*token_name) == '\0') { /* token label is required */ + cryptodebug("no token label found"); + return (-1); + } + + if (*mark == '\0' || *(mark+1) == '\0') /* no more fields */ + return (0); + token_spec = mark; + + /* Manufacturer identifier (optional) */ + mark = find_unescaped_colon(token_spec); + *manuf_id = token_spec; + if (*mark != '\0') + *mark++ = '\0'; /* mark points to next field, if any */ + unescape_str(*manuf_id); + + if (*mark == '\0' || *(mark+1) == '\0') /* no more fields */ + return (0); + token_spec = mark; + + /* Serial number (optional) */ + mark = find_unescaped_colon(token_spec); + *serial_no = token_spec; + if (*mark != '\0') + *mark++ = '\0'; /* null-terminate, just in case */ + unescape_str(*serial_no); + + return (0); +} + +/* * Constructs a fully qualified token name from its label, manufacturer ID * (if any), and its serial number (if any). Note that the given buf must * be big enough. Do NOT i18n/l10n. @@ -1081,3 +1209,116 @@ *buf = (CK_DATE *)attr->pValue; *buflen = attr->ulValueLen; } + +/* + * Breaks out the getopt-style option string into a structure that can be + * traversed later for calls to getopt_av(). Option string is NOT altered, + * but the struct fields point to locations within option string. + */ +static int +populate_opts(char *optstring) +{ + int i; + av_opts *temp; + char *marker; + + if (optstring == NULL || *optstring == '\0') + return (0); + + /* + * This tries to imitate getopt(3c) Each option must conform to: + * <short name char> [ ':' ] [ '(' <long name string> ')' ] + * If long name is missing, the short name is used for long name. + */ + for (i = 0; *optstring != '\0'; i++) { + if ((temp = (av_opts *)((i == 0) ? malloc(sizeof (av_opts)) : + realloc(opts_av, (i+1) * sizeof (av_opts)))) == NULL) { + free(opts_av); + opts_av = NULL; + return (0); + } else + opts_av = (av_opts *)temp; + + marker = optstring; /* may need optstring later */ + + opts_av[i].shortnm = *marker++; /* set short name */ + + if (*marker == ':') { /* check for opt arg */ + marker++; + opts_av[i].has_arg = B_TRUE; + } + + if (*marker == '(') { /* check and set long name */ + marker++; + opts_av[i].longnm = marker; + opts_av[i].longnm_len = strcspn(marker, ")"); + optstring = marker + opts_av[i].longnm_len + 1; + } else { + /* use short name option character */ + opts_av[i].longnm = optstring; + opts_av[i].longnm_len = 1; + optstring = marker; + } + } + + return (i); +} + +/* + * getopt_av() is very similar to getopt(3c) in that the takes an option + * string, compares command line arguments for matches, and returns a single + * letter option when a match is found. However, getopt_av() differs from + * getopt(3c) by requiring that only longname options and values be found + * on the command line and all leading dashes are omitted. In other words, + * it tries to enforce only longname "option=value" arguments on the command + * line. Boolean options are not allowed either. + */ +int +getopt_av(int argc, char * const *argv, const char *optstring) +{ + int i; + int len; + + if (optind_av >= argc) + return (EOF); + + /* First time or when optstring changes from previous one */ + if (_save_optstr != optstring) { + if (opts_av != NULL) + free(opts_av); + opts_av = NULL; + _save_optstr = optstring; + _save_numopts = populate_opts((char *)optstring); + } + + for (i = 0; i < _save_numopts; i++) { + if (strcmp(argv[optind_av], "--") == 0) { + optind_av++; + break; + } + + len = strcspn(argv[optind_av], "="); + + if (len == opts_av[i].longnm_len && strncmp(argv[optind_av], + opts_av[i].longnm, opts_av[i].longnm_len) == 0) { + /* matched */ + if (!opts_av[i].has_arg) { + optind_av++; + return (opts_av[i].shortnm); + } + + /* needs optarg */ + if (argv[optind_av][len] == '=') { + optarg_av = &(argv[optind_av][len+1]); + optind_av++; + return (opts_av[i].shortnm); + } + + optarg_av = NULL; + optind_av++; + return ((int)'?'); + } + } + + return (EOF); +}
--- a/usr/src/cmd/cmd-crypto/pktool/common.h Mon Nov 07 17:36:34 2005 -0800 +++ b/usr/src/cmd/cmd-crypto/pktool/common.h Mon Nov 07 17:38:08 2005 -0800 @@ -104,6 +104,8 @@ extern CK_RV find_objs(CK_SESSION_HANDLE sess, int obj_type, CK_BYTE *label, CK_OBJECT_HANDLE_PTR *obj, CK_ULONG *count); +extern int parse_token_spec(char *spec, char **label, char **manuf, + char **buf); extern void full_token_name(char *token, char *manuf, char *serial, char *buf); @@ -124,6 +126,10 @@ extern void copy_attr_to_date(CK_ATTRIBUTE_PTR attr, CK_DATE **buf, CK_ULONG *buflen); +extern int getopt_av(int argc, char * const argv[], const char *optstring); +extern char *optarg_av; +extern int optind_av; + #ifdef __cplusplus } #endif
--- a/usr/src/cmd/cmd-crypto/pktool/delete.c Mon Nov 07 17:36:34 2005 -0800 +++ b/usr/src/cmd/cmd-crypto/pktool/delete.c Mon Nov 07 17:38:08 2005 -0800 @@ -45,11 +45,13 @@ pk_delete(int argc, char *argv[]) { int opt; - extern int optind; - extern char *optarg; + extern int optind_av; + extern char *optarg_av; + char *token_spec = NULL; char *token_name = NULL; char *manuf_id = NULL; char *serial_no = NULL; + char *type_spec = NULL; char full_name[FULL_NAME_LEN]; boolean_t public_objs = B_FALSE; boolean_t private_objs = B_FALSE; @@ -69,21 +71,23 @@ cryptodebug("inside pk_delete"); /* Parse command line options. Do NOT i18n/l10n. */ - while ((opt = getopt(argc, argv, "p(private)P(public)l:(label)")) != - EOF) { + while ((opt = getopt_av(argc, argv, + "T:(token)y:(objtype)l:(label)")) != EOF) { switch (opt) { - case 'p': /* private objects */ - private_objs = B_TRUE; - obj_type |= PK_PRIVATE_OBJ; + case 'T': /* token specifier */ + if (token_spec) + return (PK_ERR_USAGE); + token_spec = optarg_av; break; - case 'P': /* public objects */ - public_objs = B_TRUE; - obj_type |= PK_PUBLIC_OBJ; + case 'y': /* object type: public, private, both */ + if (type_spec) + return (PK_ERR_USAGE); + type_spec = optarg_av; break; case 'l': /* objects with specific label */ if (object_label) return (PK_ERR_USAGE); - object_label = (CK_BYTE *)optarg; + object_label = (CK_BYTE *)optarg_av; break; default: return (PK_ERR_USAGE); @@ -91,6 +95,45 @@ } } + /* If no token is specified, default is to use softtoken. */ + if (token_spec == NULL) { + token_name = SOFT_TOKEN_LABEL; + manuf_id = SOFT_MANUFACTURER_ID; + serial_no = SOFT_TOKEN_SERIAL; + } else { + /* + * Parse token specifier into token_name, manuf_id, serial_no. + * Token_name is required; manuf_id and serial_no are optional. + */ + if (parse_token_spec(token_spec, &token_name, &manuf_id, + &serial_no) < 0) + return (PK_ERR_USAGE); + } + + /* If no object type specified, default is public objects. */ + if (!type_spec) { + public_objs = B_TRUE; + } else { + /* + * Otherwise, the object type must be "public", "private", + * or "both". + */ + if (strcmp(type_spec, "private") == 0) { + private_objs = B_TRUE; + } else if (strcmp(type_spec, "public") == 0) { + public_objs = B_TRUE; + } else if (strcmp(type_spec, "both") == 0) { + private_objs = B_TRUE; + public_objs = B_TRUE; + } else + return (PK_ERR_USAGE); + } + + if (private_objs) + obj_type |= PK_PRIVATE_OBJ; + if (public_objs) + obj_type |= PK_PUBLIC_OBJ; + /* At least one of public, private, or object label is required. */ if (!private_objs && !public_objs && object_label == NULL) return (PK_ERR_USAGE); @@ -103,19 +146,12 @@ obj_type = PK_ALL_OBJ; /* No additional args allowed. */ - argc -= optind; - argv += optind; + argc -= optind_av; + argv += optind_av; if (argc) return (PK_ERR_USAGE); /* Done parsing command line options. */ - /* Delete operation only supported on softtoken. */ - if (token_name == NULL) - token_name = SOFT_TOKEN_LABEL; - if (manuf_id == NULL) - manuf_id = SOFT_MANUFACTURER_ID; - if (serial_no == NULL) - serial_no = SOFT_TOKEN_SERIAL; full_token_name(token_name, manuf_id, serial_no, full_name); /* Find the slot with token. */
--- a/usr/src/cmd/cmd-crypto/pktool/export.c Mon Nov 07 17:36:34 2005 -0800 +++ b/usr/src/cmd/cmd-crypto/pktool/export.c Mon Nov 07 17:38:08 2005 -0800 @@ -1201,6 +1201,10 @@ int pk_export(int argc, char *argv[]) { + int opt; + extern int optind_av; + extern char *optarg_av; + char *token_spec = NULL; char *token_name = NULL; char *manuf_id = NULL; char *serial_no = NULL; @@ -1230,15 +1234,49 @@ cryptodebug("inside pk_export"); - /* Get rid of subcommand work "export". */ - argc--; - argv++; + /* Parse command line options. Do NOT i18n/l10n. */ + while ((opt = getopt_av(argc, argv, "T:(token)o:(outfile)")) != EOF) { + switch (opt) { + case 'T': /* token specifier */ + if (token_spec) + return (PK_ERR_USAGE); + token_spec = optarg_av; + break; + case 'o': /* output file name */ + if (filename) + return (PK_ERR_USAGE); + filename = optarg_av; + break; + default: + return (PK_ERR_USAGE); + break; + } + } - /* One additional arg required: filename. */ - if (argc != 1) + /* If nothing is specified, default is to use softtoken. */ + if (token_spec == NULL) { + token_name = SOFT_TOKEN_LABEL; + manuf_id = SOFT_MANUFACTURER_ID; + serial_no = SOFT_TOKEN_SERIAL; + } else { + /* + * Parse token specifier into token_name, manuf_id, serial_no. + * Token_name is required; manuf_id and serial_no are optional. + */ + if (parse_token_spec(token_spec, &token_name, &manuf_id, + &serial_no) < 0) + return (PK_ERR_USAGE); + } + + /* Filename arg is required. */ + if (filename == NULL) return (PK_ERR_USAGE); - filename = argv[0]; + /* No additional args allowed. */ + argc -= optind_av; + argv += optind_av; + if (argc) + return (PK_ERR_USAGE); /* Done parsing command line options. */ /* Check if the file exists and might be overwritten. */ @@ -1251,13 +1289,6 @@ } } - /* Export operation only supported on softtoken. */ - if (token_name == NULL) - token_name = SOFT_TOKEN_LABEL; - if (manuf_id == NULL) - manuf_id = SOFT_MANUFACTURER_ID; - if (serial_no == NULL) - serial_no = SOFT_TOKEN_SERIAL; full_token_name(token_name, manuf_id, serial_no, full_name); /* Find the slot with token. */
--- a/usr/src/cmd/cmd-crypto/pktool/import.c Mon Nov 07 17:36:34 2005 -0800 +++ b/usr/src/cmd/cmd-crypto/pktool/import.c Mon Nov 07 17:38:08 2005 -0800 @@ -789,6 +789,10 @@ int pk_import(int argc, char *argv[]) { + int opt; + extern int optind_av; + extern char *optarg_av; + char *token_spec = NULL; char *token_name = NULL; char *manuf_id = NULL; char *serial_no = NULL; @@ -812,15 +816,49 @@ cryptodebug("inside pk_import"); - /* Get rid of subcommand word "import". */ - argc--; - argv++; + /* Parse command line options. Do NOT i18n/l10n. */ + while ((opt = getopt_av(argc, argv, "T:(token)i:(infile)")) != EOF) { + switch (opt) { + case 'T': /* token specifier */ + if (token_spec) + return (PK_ERR_USAGE); + token_spec = optarg_av; + break; + case 'i': /* input file name */ + if (filename) + return (PK_ERR_USAGE); + filename = optarg_av; + break; + default: + return (PK_ERR_USAGE); + break; + } + } - /* One additional arg required: filename. */ - if (argc != 1) + /* If nothing is specified, default is to use softtoken. */ + if (token_spec == NULL) { + token_name = SOFT_TOKEN_LABEL; + manuf_id = SOFT_MANUFACTURER_ID; + serial_no = SOFT_TOKEN_SERIAL; + } else { + /* + * Parse token specifier into token_name, manuf_id, serial_no. + * Token_name is required; manuf_id and serial_no are optional. + */ + if (parse_token_spec(token_spec, &token_name, &manuf_id, + &serial_no) < 0) + return (PK_ERR_USAGE); + } + + /* Filename arg is required. */ + if (filename == NULL) return (PK_ERR_USAGE); - filename = argv[0]; + /* No additional args allowed. */ + argc -= optind_av; + argv += optind_av; + if (argc) + return (PK_ERR_USAGE); /* Done parsing command line options. */ /* Check that the file exists and is non-empty. */ @@ -840,13 +878,6 @@ return (CKR_OK); } - /* Import operation only supported on softtoken. */ - if (token_name == NULL) - token_name = SOFT_TOKEN_LABEL; - if (manuf_id == NULL) - manuf_id = SOFT_MANUFACTURER_ID; - if (serial_no == NULL) - serial_no = SOFT_TOKEN_SERIAL; full_token_name(token_name, manuf_id, serial_no, full_name); /* Find the slot with token. */
--- a/usr/src/cmd/cmd-crypto/pktool/list.c Mon Nov 07 17:36:34 2005 -0800 +++ b/usr/src/cmd/cmd-crypto/pktool/list.c Mon Nov 07 17:38:08 2005 -0800 @@ -837,11 +837,13 @@ pk_list(int argc, char *argv[]) { int opt; - extern int optind; - extern char *optarg; + extern int optind_av; + extern char *optarg_av; + char *token_spec = NULL; char *token_name = NULL; char *manuf_id = NULL; char *serial_no = NULL; + char *type_spec = NULL; char full_name[FULL_NAME_LEN]; boolean_t public_objs = B_FALSE; boolean_t private_objs = B_FALSE; @@ -863,21 +865,23 @@ cryptodebug("inside pk_list"); /* Parse command line options. Do NOT i18n/l10n. */ - while ((opt = getopt(argc, argv, "p(private)P(public)l:(label)")) != - EOF) { + while ((opt = getopt_av(argc, argv, + "T:(token)y:(objtype)l:(label)")) != EOF) { switch (opt) { - case 'p': /* private objects */ - private_objs = B_TRUE; - obj_type |= PK_PRIVATE_OBJ; + case 'T': /* token specifier */ + if (token_spec) + return (PK_ERR_USAGE); + token_spec = optarg_av; break; - case 'P': /* public objects */ - public_objs = B_TRUE; - obj_type |= PK_PUBLIC_OBJ; + case 'y': /* object type: public, private, both */ + if (type_spec) + return (PK_ERR_USAGE); + type_spec = optarg_av; break; case 'l': /* object with specific label */ if (list_label) return (PK_ERR_USAGE); - list_label = (CK_BYTE *)optarg; + list_label = (CK_BYTE *)optarg_av; break; default: return (PK_ERR_USAGE); @@ -885,26 +889,52 @@ } } - /* If nothing specified, default is public objects. */ - if (!public_objs && !private_objs) { - public_objs = B_TRUE; - obj_type |= PK_PUBLIC_OBJ; + /* If no token is specified, default is to use softtoken. */ + if (token_spec == NULL) { + token_name = SOFT_TOKEN_LABEL; + manuf_id = SOFT_MANUFACTURER_ID; + serial_no = SOFT_TOKEN_SERIAL; + } else { + /* + * Parse token specifier into token_name, manuf_id, serial_no. + * Token_name is required; manuf_id and serial_no are optional. + */ + if (parse_token_spec(token_spec, &token_name, &manuf_id, + &serial_no) < 0) + return (PK_ERR_USAGE); } + /* If no object type specified, default is public objects. */ + if (!type_spec) { + public_objs = B_TRUE; + } else { + /* + * Otherwise, the object type must be "public", "private", + * or "both". + */ + if (strcmp(type_spec, "private") == 0) { + private_objs = B_TRUE; + } else if (strcmp(type_spec, "public") == 0) { + public_objs = B_TRUE; + } else if (strcmp(type_spec, "both") == 0) { + private_objs = B_TRUE; + public_objs = B_TRUE; + } else + return (PK_ERR_USAGE); + } + + if (private_objs) + obj_type |= PK_PRIVATE_OBJ; + if (public_objs) + obj_type |= PK_PUBLIC_OBJ; + /* No additional args allowed. */ - argc -= optind; - argv += optind; + argc -= optind_av; + argv += optind_av; if (argc) return (PK_ERR_USAGE); /* Done parsing command line options. */ - /* List operation only supported on softtoken. */ - if (token_name == NULL) - token_name = SOFT_TOKEN_LABEL; - if (manuf_id == NULL) - manuf_id = SOFT_MANUFACTURER_ID; - if (serial_no == NULL) - serial_no = SOFT_TOKEN_SERIAL; full_token_name(token_name, manuf_id, serial_no, full_name); /* Find the slot with token. */
--- a/usr/src/cmd/cmd-crypto/pktool/pktool.c Mon Nov 07 17:36:34 2005 -0800 +++ b/usr/src/cmd/cmd-crypto/pktool/pktool.c Mon Nov 07 17:38:08 2005 -0800 @@ -69,15 +69,19 @@ /* Command structure for verbs and their actions. Do NOT i18n/l10n. */ static verbcmd cmds[] = { { "tokens", pk_tokens, 0, "tokens" }, - { "setpin", pk_setpin, 0, "setpin" }, - { "list", pk_list, 0, "list [-p] [-P] [-l <label>]" - "\n\t\tor list [--public] [--private] [--label[=]<label>]" }, + { "setpin", pk_setpin, 0, + "setpin [token=<token>[:<manuf>[:<serial>]]]" }, + { "list", pk_list, 0, + "list [token=<token>[:<manuf>[:<serial>]]] " + "[objtype=private|public|both] [label=<label>]" }, { "delete", pk_delete, 0, - "delete { [-p] [-P] [-l <label>] }" - "\n\t\tor delete { [--public] [--private] [--label[=]<label>] }" }, - { "import", pk_import, 0, "import <file>" }, - { "export", pk_export, 0, "export <file>" }, - { "-?", pk_help, 0, "--help\t(help and usage)" }, + "delete [token=<token>[:<manuf>[:<serial>]]] " + "{ [objtype=private|public|both] [label=<label>] }" }, + { "import", pk_import, 0, + "import [token=<token>[:<manuf>[:<serial>]]] infile=<file>" }, + { "export", pk_export, 0, + "export [token=<token>[:<manuf>[:<serial>]]] outfile=<file>" }, + { "-?", pk_help, 0, "help\t(help and usage)" }, }; static int num_cmds = sizeof (cmds) / sizeof (verbcmd);
--- a/usr/src/cmd/cmd-crypto/pktool/setpin.c Mon Nov 07 17:36:34 2005 -0800 +++ b/usr/src/cmd/cmd-crypto/pktool/setpin.c Mon Nov 07 17:38:08 2005 -0800 @@ -48,6 +48,10 @@ pk_setpin(int argc, char *argv[]) /* ARGSUSED */ { + int opt; + extern int optind_av; + extern char *optarg_av; + char *token_spec = NULL; char *token_name = NULL; char *manuf_id = NULL; char *serial_no = NULL; @@ -61,26 +65,42 @@ cryptodebug("inside pk_setpin"); - /* Get rid of subcommand word "setpin". */ - argc--; - argv++; + /* Parse command line options. Do NOT i18n/l10n. */ + while ((opt = getopt_av(argc, argv, "T:(token)")) != EOF) { + switch (opt) { + case 'T': /* token specifier */ + if (token_spec) + return (PK_ERR_USAGE); + token_spec = optarg_av; + break; + default: + return (PK_ERR_USAGE); + break; + } + } + + /* If nothing is specified, default is to use softtoken. */ + if (token_spec == NULL) { + token_name = SOFT_TOKEN_LABEL; + manuf_id = SOFT_MANUFACTURER_ID; + serial_no = SOFT_TOKEN_SERIAL; + } else { + /* + * Parse token specifier into token_name, manuf_id, serial_no. + * Token_name is required; manuf_id and serial_no are optional. + */ + if (parse_token_spec(token_spec, &token_name, &manuf_id, + &serial_no) < 0) + return (PK_ERR_USAGE); + } /* No additional args allowed. */ + argc -= optind_av; + argv += optind_av; if (argc != 0) return (PK_ERR_USAGE); /* Done parsing command line options. */ - /* - * Token_name, manuf_id, and serial_no are all optional. - * If unspecified, token_name must have a default value - * at least, so set it to the default softtoken value. - */ - if (token_name == NULL) - token_name = SOFT_TOKEN_LABEL; - if (manuf_id == NULL) - manuf_id = SOFT_MANUFACTURER_ID; - if (serial_no == NULL) - serial_no = SOFT_TOKEN_SERIAL; full_token_name(token_name, manuf_id, serial_no, full_name); /* Find the slot with token. */