diff options
Diffstat (limited to 'usr/src/cmd/cmd-crypto/pktool/setpin.c')
-rw-r--r-- | usr/src/cmd/cmd-crypto/pktool/setpin.c | 264 |
1 files changed, 178 insertions, 86 deletions
diff --git a/usr/src/cmd/cmd-crypto/pktool/setpin.c b/usr/src/cmd/cmd-crypto/pktool/setpin.c index 038f57169e..62416e8c7d 100644 --- a/usr/src/cmd/cmd-crypto/pktool/setpin.c +++ b/usr/src/cmd/cmd-crypto/pktool/setpin.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. */ @@ -41,76 +40,90 @@ #include <security/cryptoki.h> #include "common.h" -/* - * Changes the token's PIN. - */ -int -pk_setpin(int argc, char *argv[]) -/* ARGSUSED */ +static int +setpin_nss(KMF_HANDLE_T handle, + char *token_spec, char *dir, char *prefix) { - 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; - CK_SLOT_ID slot_id; - CK_FLAGS pin_state; - CK_SESSION_HANDLE sess; + int rv = 0; + KMF_SETPIN_PARAMS params; + KMF_CREDENTIAL newpincred = { NULL, 0 }; CK_UTF8CHAR_PTR old_pin = NULL, new_pin = NULL; CK_ULONG old_pinlen = 0, new_pinlen = 0; - CK_RV rv = CKR_OK; - char full_name[FULL_NAME_LEN]; - cryptodebug("inside pk_setpin"); + rv = configure_nss(handle, dir, prefix); + if (rv != KMF_OK) + return (rv); - /* 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; - } + (void) memset(¶ms, 0, sizeof (params)); + params.kstype = KMF_KEYSTORE_NSS; + params.tokenname = token_spec; + params.nssparms.slotlabel = token_spec; + + if ((rv = get_pin(gettext("Enter current token passphrase " + "(<CR> if not set):"), NULL, &old_pin, &old_pinlen)) != + CKR_OK) { + cryptoerror(LOG_STDERR, + gettext("Unable to get token passphrase.")); + return (PK_ERR_NSS); } + /* Get the user's new PIN. */ + if ((rv = get_pin(gettext("Create new passphrase:"), gettext( + "Re-enter new passphrase:"), &new_pin, &new_pinlen)) != CKR_OK) { + if (rv == CKR_PIN_INCORRECT) + cryptoerror(LOG_STDERR, gettext( + "Passphrases do not match.")); + else + cryptoerror(LOG_STDERR, gettext( + "Unable to get and confirm new passphrase.")); + if (old_pin != NULL) + free(old_pin); + return (PK_ERR_NSS); + } + + params.cred.cred = (char *)old_pin; + params.cred.credlen = old_pinlen; + + newpincred.cred = (char *)new_pin; + newpincred.credlen = new_pinlen; + + rv = KMF_SetTokenPin(handle, ¶ms, &newpincred); + + if (new_pin) + free(new_pin); + if (old_pin) + free(old_pin); + + return (rv); +} + +static int +setpin_pkcs11(KMF_HANDLE_T handle, char *token_spec) +{ + CK_SLOT_ID slot_id; + CK_FLAGS pin_state; + CK_UTF8CHAR_PTR old_pin = NULL, new_pin = NULL; + CK_ULONG old_pinlen = 0, new_pinlen = 0; + CK_RV rv = CKR_OK; + char *token_name = NULL; + KMF_SETPIN_PARAMS params; + CK_TOKEN_INFO token_info; + KMF_CREDENTIAL newpincred = { NULL, 0 }; /* If nothing is specified, default is to use softtoken. */ if (token_spec == NULL) { + token_spec = SOFT_TOKEN_LABEL ":" SOFT_MANUFACTURER_ID; 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. */ - - full_token_name(token_name, manuf_id, serial_no, full_name); + rv = KMF_PK11TokenLookup(NULL, token_spec, &slot_id); + if (rv == KMF_OK) { + /* find the pin state for the selected token */ + if (C_GetTokenInfo(slot_id, &token_info) != CKR_OK) + return (PK_ERR_PK11); - /* Find the slot with token. */ - if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, - &pin_state)) != CKR_OK) { - cryptoerror(LOG_STDERR, - gettext("Unable to find token %s (%s)."), full_name, - pkcs11_strerror(rv)); - final_pk11(NULL); - return (PK_ERR_PK11); + pin_state = token_info.flags & CKF_USER_PIN_TO_BE_CHANGED; + if (token_name == NULL) + token_name = (char *)token_info.label; } /* @@ -121,7 +134,6 @@ pk_setpin(int argc, char *argv[]) */ if (pin_state == CKF_USER_PIN_TO_BE_CHANGED && strcmp(token_name, SOFT_TOKEN_LABEL) == 0) { - cryptodebug("pin_state: first time passphrase is being set"); if ((old_pin = (CK_UTF8CHAR_PTR) strdup(SOFT_DEFAULT_PIN)) == NULL) { cryptoerror(LOG_STDERR, "%s.", strerror(errno)); @@ -130,7 +142,6 @@ pk_setpin(int argc, char *argv[]) } old_pinlen = strlen(SOFT_DEFAULT_PIN); } else { - cryptodebug("pin_state: changing an existing pin "); if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, &old_pin, &old_pinlen)) != CKR_OK) { cryptoerror(LOG_STDERR, @@ -156,36 +167,117 @@ pk_setpin(int argc, char *argv[]) return (PK_ERR_PK11); } - /* Open a R/W session to the token to change the PIN. */ - if ((rv = open_sess(slot_id, CKF_RW_SESSION, &sess)) != CKR_OK) { - cryptoerror(LOG_STDERR, - gettext("Unable to open token session (%s)."), - pkcs11_strerror(rv)); + (void) memset(¶ms, 0, sizeof (params)); + params.kstype = KMF_KEYSTORE_PK11TOKEN; + params.tokenname = (char *)token_info.label; + params.cred.cred = (char *)old_pin; + params.cred.credlen = old_pinlen; + params.pkcs11parms.slot = slot_id; + + newpincred.cred = (char *)new_pin; + newpincred.credlen = new_pinlen; + + rv = KMF_SetTokenPin(handle, ¶ms, &newpincred); + + /* Clean up. */ + if (old_pin != NULL) free(old_pin); - final_pk11(NULL); - return (PK_ERR_PK11); + if (new_pin != NULL) + free(new_pin); + + return (rv); +} + +/* + * Changes the token's PIN. + */ +int +pk_setpin(int argc, char *argv[]) +/* ARGSUSED */ +{ + int opt; + int rv; + extern int optind_av; + extern char *optarg_av; + char *token_spec = NULL; + char *dir = NULL; + char *prefix = NULL; + KMF_HANDLE_T handle; + KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN; + + /* Parse command line options. Do NOT i18n/l10n. */ + while ((opt = getopt_av(argc, argv, + "T:(token)k:(keystore)d:(dir)" + "p:(prefix)")) != EOF) { + switch (opt) { + case 'k': + kstype = KS2Int(optarg_av); + if (kstype == 0) + return (PK_ERR_USAGE); + break; + case 'T': /* token specifier */ + if (token_spec) + return (PK_ERR_USAGE); + token_spec = optarg_av; + break; + case 'd': + if (dir) + return (PK_ERR_USAGE); + dir = optarg_av; + break; + case 'p': + if (prefix) + return (PK_ERR_USAGE); + prefix = optarg_av; + break; + default: + return (PK_ERR_USAGE); + break; + } } - /* Change the PIN if possible. */ - cryptodebug("calling C_SetPIN"); - rv = C_SetPIN(sess, old_pin, old_pinlen, new_pin, new_pinlen); - /* Clean up. */ - free(old_pin); - free(new_pin); - quick_finish(sess); + /* No additional args allowed. */ + argc -= optind_av; + argv += optind_av; + if (argc != 0) + return (PK_ERR_USAGE); - if (rv != CKR_OK) { - if (rv == CKR_PIN_INCORRECT) - cryptoerror(LOG_STDERR, - gettext("Incorrect passphrase.")); - else + /* Done parsing command line options. */ + if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) { + token_spec = PK_DEFAULT_PK11TOKEN; + } else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) { + token_spec = DEFAULT_NSS_TOKEN; + } + + if ((rv = KMF_Initialize(&handle, NULL, NULL)) != KMF_OK) + return (rv); + + switch (kstype) { + case KMF_KEYSTORE_PK11TOKEN: + rv = setpin_pkcs11(handle, token_spec); + break; + case KMF_KEYSTORE_NSS: + rv = setpin_nss(handle, token_spec, dir, prefix); + break; + default: cryptoerror(LOG_STDERR, - gettext("Unable to change passphrase (%s)."), - pkcs11_strerror(rv)); - return (PK_ERR_PK11); + gettext("incorrect keystore.")); + return (PK_ERR_USAGE); } - (void) fprintf(stdout, gettext("Passphrase changed.\n")); + (void) KMF_Finalize(handle); + + if (rv == KMF_ERR_AUTH_FAILED) { + cryptoerror(LOG_STDERR, + gettext("Incorrect passphrase.")); + return (PK_ERR_SYSTEM); + } else if (rv != CKR_OK) { + cryptoerror(LOG_STDERR, + gettext("Unable to change passphrase.")); + return (PK_ERR_SYSTEM); + } else { + (void) fprintf(stdout, gettext("Passphrase changed.\n")); + } return (0); } |